+++ /dev/null
-**Note: This file is only relevant for legacy contributions, to acknowledge the
-specific contributors referred to in "Arm Limited and Contributors" copyright
-notices. As contributors are now encouraged to put their name or company name
-directly into the copyright notices, this file is not relevant for new
-contributions.**
-
-Contributor Acknowledgements
-============================
-
-Companies
----------
-
-Linaro Limited
-
-NVIDIA Corporation
-
-Socionext Inc.
-
-Xilinx, Inc.
-
-NXP Semiconductors
-
-Marvell International Ltd.
-
-STMicroelectronics
-
-Individuals
------------
+++ /dev/null
-Contributing to Trusted Firmware-A
-==================================
-
-Getting Started
----------------
-
-- Make sure you have a Github account and you are logged on
- `developer.trustedfirmware.org`_.
-- Create an `issue`_ for your work if one does not already exist. This gives
- everyone visibility of whether others are working on something similar.
-
- - If you intend to include Third Party IP in your contribution, please
- raise a separate `issue`_ for this and ensure that the changes that
- include Third Party IP are made on a separate topic branch.
-
-- Clone `arm-trusted-firmware-a`_ on your own machine as suggested on the
- `User Guide`_.
-- Create a local topic branch based on the `arm-trusted-firmware-a`_ ``master``
- branch.
-
-Making Changes
---------------
-
-- Make commits of logical units. See these general `Git guidelines`_ for
- contributing to a project.
-- Follow the `Coding Guidelines`_.
-
- - Use the checkpatch.pl script provided with the Linux source tree. A
- Makefile target is provided for convenience (see the "Checking source code
- style" section in the `User Guide`_).
-
-- Keep the commits on topic. If you need to fix another bug or make another
- enhancement, please create a separate `issue`_ and address it on a separate
- topic branch.
-- Avoid long commit series. If you do have a long series, consider whether
- some commits should be squashed together or addressed in a separate topic.
-- Make sure your commit messages are in the proper format. If a commit fixes
- an `issue`_, include a reference.
-- Where appropriate, please update the documentation.
-
- - Consider whether the `User Guide`_, `Porting Guide`_, `Firmware Design`_
- or other in-source documentation needs updating.
- - Ensure that each changed file has the correct copyright and license
- information. Files that entirely consist of contributions to this
- project should have a copyright notice and BSD-3-Clause SPDX license
- identifier of the form as shown in `license.rst`_. Files that contain
- changes to imported Third Party IP files should retain their original
- copyright and license notices. For significant contributions you may
- add your own copyright notice in following format:
-
- ::
-
- Portions copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
-
- where XXXX is the year of first contribution (if different to YYYY) and
- YYYY is the year of most recent contribution. <OWNER> is your name or
- your company name.
- - If you are submitting new files that you intend to be the technical
- sub-maintainer for (for example, a new platform port), then also update
- the `Maintainers`_ file.
- - For topics with multiple commits, you should make all documentation
- changes (and nothing else) in the last commit of the series. Otherwise,
- include the documentation changes within the single commit.
-
-- Please test your changes. As a minimum, ensure that Linux boots on the
- Foundation FVP. See `Running the software on FVP`_ for more information. For
- more extensive testing, consider running the `TF-A Tests`_ against your
- patches.
-
-Submitting Changes
-------------------
-
-- Ensure that each commit in the series has at least one ``Signed-off-by:``
- line, using your real name and email address. The names in the
- ``Signed-off-by:`` and ``Author:`` lines must match. If anyone else
- contributes to the commit, they must also add their own ``Signed-off-by:``
- line. By adding this line the contributor certifies the contribution is made
- under the terms of the `Developer Certificate of Origin (DCO)`_.
-
- More details may be found in the `Gerrit Signed-off-by Lines guidelines`_.
-
-- Ensure that each commit also has a unique ``Change-Id:`` line. If you have
- cloned the repository with the "`Clone with commit-msg hook`" clone method
- (as advised on the `User Guide`_), this should already be the case.
-
- More details may be found in the `Gerrit Change-Ids documentation`_.
-
-- Submit your changes for review at https://review.trustedfirmware.org
- targeting the ``integration`` branch.
-
- - The changes will then undergo further review and testing by the
- `Maintainers`_. Any review comments will be made directly on your patch.
- This may require you to do some rework.
-
- Refer to the `Gerrit Uploading Changes documentation`_ for more details.
-
-- When the changes are accepted, the `Maintainers`_ will integrate them.
-
- - Typically, the `Maintainers`_ will merge the changes into the
- ``integration`` branch.
- - If the changes are not based on a sufficiently-recent commit, or if they
- cannot be automatically rebased, then the `Maintainers`_ may rebase it on
- the ``master`` branch or ask you to do so.
- - After final integration testing, the changes will make their way into the
- ``master`` branch. If a problem is found during integration, the merge
- commit will be removed from the ``integration`` branch and the
- `Maintainers`_ will ask you to create a new patch set to resolve the
- problem.
-
-Binary Components
------------------
-
-- Platforms may depend on binary components submitted to the `Trusted Firmware
- binary repository`_ if they require code that the contributor is unable or
- unwilling to open-source. This should be used as a rare exception.
-- All binary components must follow the contribution guidelines (in particular
- licensing rules) outlined in the `readme.rst <tf-binaries-readme_>`_ file of
- the binary repository.
-- Binary components must be restricted to only the specific functionality that
- cannot be open-sourced and must be linked into a larger open-source platform
- port. The majority of the platform port must still be implemented in open
- source. Platform ports that are merely a thin wrapper around a binary
- component that contains all the actual code will not be accepted.
-- Only platform port code (i.e. in the ``plat/<vendor>`` directory) may rely on
- binary components. Generic code must always be fully open-source.
-
---------------
-
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
-.. _issue: https://developer.trustedfirmware.org/project/board/1/
-.. _arm-trusted-firmware-a: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
-.. _Git guidelines: http://git-scm.com/book/ch5-2.html
-.. _Coding Guidelines: ./docs/coding-guidelines.rst
-.. _User Guide: ./docs/user-guide.rst
-.. _Porting Guide: ./docs/porting-guide.rst
-.. _Firmware Design: ./docs/firmware-design.rst
-.. _license.rst: ./license.rst
-.. _Acknowledgements: ./acknowledgements.rst
-.. _Maintainers: ./maintainers.rst
-.. _Running the software on FVP: ./docs/user-guide.rst#user-content-running-the-software-on-fvp
-.. _Developer Certificate of Origin (DCO): ./dco.txt
-.. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
-.. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
-.. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
-.. _TF-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
-.. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries
-.. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst
--- /dev/null
+**Note: This file is only relevant for legacy contributions, to acknowledge the
+specific contributors referred to in "Arm Limited and Contributors" copyright
+notices. As contributors are now encouraged to put their name or company name
+directly into the copyright notices, this file is not relevant for new
+contributions.**
+
+Contributor Acknowledgements
+============================
+
+Companies
+---------
+
+Linaro Limited
+
+NVIDIA Corporation
+
+Socionext Inc.
+
+Xilinx, Inc.
+
+NXP Semiconductors
+
+Marvell International Ltd.
+
+STMicroelectronics
+
+Individuals
+-----------
+++ /dev/null
-Arm SiP Service
-===============
-
-This document enumerates and describes the Arm SiP (Silicon Provider) services.
-
-SiP services are non-standard, platform-specific services offered by the silicon
-implementer or platform provider. They are accessed via ``SMC`` ("SMC calls")
-instruction executed from Exception Levels below EL3. SMC calls for SiP
-services:
-
-- Follow `SMC Calling Convention`_;
-- Use SMC function IDs that fall in the SiP range, which are ``0xc2000000`` -
- ``0xc200ffff`` for 64-bit calls, and ``0x82000000`` - ``0x8200ffff`` for 32-bit
- calls.
-
-The Arm SiP implementation offers the following services:
-
-- Performance Measurement Framework (PMF)
-- Execution State Switching service
-
-Source definitions for Arm SiP service are located in the ``arm_sip_svc.h`` header
-file.
-
-Performance Measurement Framework (PMF)
----------------------------------------
-
-The `Performance Measurement Framework`_
-allows callers to retrieve timestamps captured at various paths in TF-A
-execution. It's described in detail in `Firmware Design document`_.
-
-Execution State Switching service
----------------------------------
-
-Execution State Switching service provides a mechanism for a non-secure lower
-Exception Level (either EL2, or NS EL1 if EL2 isn't implemented) to request to
-switch its execution state (a.k.a. Register Width), either from AArch64 to
-AArch32, or from AArch32 to AArch64, for the calling CPU. This service is only
-available when Trusted Firmware-A (TF-A) is built for AArch64 (i.e. when build
-option ``ARCH`` is set to ``aarch64``).
-
-``ARM_SIP_SVC_EXE_STATE_SWITCH``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t Function ID
- uint32_t PC hi
- uint32_t PC lo
- uint32_t Cookie hi
- uint32_t Cookie lo
-
- Return:
- uint32_t
-
-The function ID parameter must be ``0x82000020``. It uniquely identifies the
-Execution State Switching service being requested.
-
-The parameters *PC hi* and *PC lo* defines upper and lower words, respectively,
-of the entry point (physical address) at which execution should start, after
-Execution State has been switched. When calling from AArch64, *PC hi* must be 0.
-
-When execution starts at the supplied entry point after Execution State has been
-switched, the parameters *Cookie hi* and *Cookie lo* are passed in CPU registers
-0 and 1, respectively. When calling from AArch64, *Cookie hi* must be 0.
-
-This call can only be made on the primary CPU, before any secondaries were
-brought up with ``CPU_ON`` PSCI call. Otherwise, the call will always fail.
-
-The effect of switching execution state is as if the Exception Level were
-entered for the first time, following power on. This means CPU registers that
-have a defined reset value by the Architecture will assume that value. Other
-registers should not be expected to hold their values before the call was made.
-CPU endianness, however, is preserved from the previous execution state. Note
-that this switches the execution state of the calling CPU only. This is not a
-substitute for PSCI ``SYSTEM_RESET``.
-
-The service may return the following error codes:
-
-- ``STATE_SW_E_PARAM``: If any of the parameters were deemed invalid for
- a specific request.
-- ``STATE_SW_E_DENIED``: If the call is not successful, or when TF-A is
- built for AArch32.
-
-If the call is successful, the caller wouldn't observe the SMC returning.
-Instead, execution starts at the supplied entry point, with the CPU registers 0
-and 1 populated with the supplied *Cookie hi* and *Cookie lo* values,
-respectively.
-
---------------
-
-*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
-.. _Performance Measurement Framework: ./firmware-design.rst#user-content-performance-measurement-framework
-.. _Firmware Design document: ./firmware-design.rst
+++ /dev/null
-Abstracting a Chain of Trust
-============================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-The aim of this document is to describe the authentication framework
-implemented in Trusted Firmware-A (TF-A). This framework fulfills the
-following requirements:
-
-#. It should be possible for a platform port to specify the Chain of Trust in
- terms of certificate hierarchy and the mechanisms used to verify a
- particular image/certificate.
-
-#. The framework should distinguish between:
-
- - The mechanism used to encode and transport information, e.g. DER encoded
- X.509v3 certificates to ferry Subject Public Keys, hashes and non-volatile
- counters.
-
- - The mechanism used to verify the transported information i.e. the
- cryptographic libraries.
-
-The framework has been designed following a modular approach illustrated in the
-next diagram:
-
-::
-
- +---------------+---------------+------------+
- | Trusted | Trusted | Trusted |
- | Firmware | Firmware | Firmware |
- | Generic | IO Framework | Platform |
- | Code i.e. | (IO) | Port |
- | BL1/BL2 (GEN) | | (PP) |
- +---------------+---------------+------------+
- ^ ^ ^
- | | |
- v v v
- +-----------+ +-----------+ +-----------+
- | | | | | Image |
- | Crypto | | Auth | | Parser |
- | Module |<->| Module |<->| Module |
- | (CM) | | (AM) | | (IPM) |
- | | | | | |
- +-----------+ +-----------+ +-----------+
- ^ ^
- | |
- v v
- +----------------+ +-----------------+
- | Cryptographic | | Image Parser |
- | Libraries (CL) | | Libraries (IPL) |
- +----------------+ +-----------------+
- | |
- | |
- | |
- v v
- +-----------------+
- | Misc. Libs e.g. |
- | ASN.1 decoder |
- | |
- +-----------------+
-
- DIAGRAM 1.
-
-This document describes the inner details of the authentication framework and
-the abstraction mechanisms available to specify a Chain of Trust.
-
-Framework design
-----------------
-
-This section describes some aspects of the framework design and the rationale
-behind them. These aspects are key to verify a Chain of Trust.
-
-Chain of Trust
-~~~~~~~~~~~~~~
-
-A CoT is basically a sequence of authentication images which usually starts with
-a root of trust and culminates in a single data image. The following diagram
-illustrates how this maps to a CoT for the BL31 image described in the
-`TBBR-Client specification`_.
-
-::
-
- +------------------+ +-------------------+
- | ROTPK/ROTPK Hash |------>| Trusted Key |
- +------------------+ | Certificate |
- | (Auth Image) |
- /+-------------------+
- / |
- / |
- / |
- / |
- L v
- +------------------+ +-------------------+
- | Trusted World |------>| BL31 Key |
- | Public Key | | Certificate |
- +------------------+ | (Auth Image) |
- +-------------------+
- / |
- / |
- / |
- / |
- / v
- +------------------+ L +-------------------+
- | BL31 Content |------>| BL31 Content |
- | Certificate PK | | Certificate |
- +------------------+ | (Auth Image) |
- +-------------------+
- / |
- / |
- / |
- / |
- / v
- +------------------+ L +-------------------+
- | BL31 Hash |------>| BL31 Image |
- | | | (Data Image) |
- +------------------+ | |
- +-------------------+
-
- DIAGRAM 2.
-
-The root of trust is usually a public key (ROTPK) that has been burnt in the
-platform and cannot be modified.
-
-Image types
-~~~~~~~~~~~
-
-Images in a CoT are categorised as authentication and data images. An
-authentication image contains information to authenticate a data image or
-another authentication image. A data image is usually a boot loader binary, but
-it could be any other data that requires authentication.
-
-Component responsibilities
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-For every image in a Chain of Trust, the following high level operations are
-performed to verify it:
-
-#. Allocate memory for the image either statically or at runtime.
-
-#. Identify the image and load it in the allocated memory.
-
-#. Check the integrity of the image as per its type.
-
-#. Authenticate the image as per the cryptographic algorithms used.
-
-#. If the image is an authentication image, extract the information that will
- be used to authenticate the next image in the CoT.
-
-In Diagram 1, each component is responsible for one or more of these operations.
-The responsibilities are briefly described below.
-
-TF-A Generic code and IO framework (GEN/IO)
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-These components are responsible for initiating the authentication process for a
-particular image in BL1 or BL2. For each BL image that requires authentication,
-the Generic code asks recursively the Authentication module what is the parent
-image until either an authenticated image or the ROT is reached. Then the
-Generic code calls the IO framework to load the image and calls the
-Authentication module to authenticate it, following the CoT from ROT to Image.
-
-TF-A Platform Port (PP)
-^^^^^^^^^^^^^^^^^^^^^^^
-
-The platform is responsible for:
-
-#. Specifying the CoT for each image that needs to be authenticated. Details of
- how a CoT can be specified by the platform are explained later. The platform
- also specifies the authentication methods and the parsing method used for
- each image.
-
-#. Statically allocating memory for each parameter in each image which is
- used for verifying the CoT, e.g. memory for public keys, hashes etc.
-
-#. Providing the ROTPK or a hash of it.
-
-#. Providing additional information to the IPM to enable it to identify and
- extract authentication parameters contained in an image, e.g. if the
- parameters are stored as X509v3 extensions, the corresponding OID must be
- provided.
-
-#. Fulfill any other memory requirements of the IPM and the CM (not currently
- described in this document).
-
-#. Export functions to verify an image which uses an authentication method that
- cannot be interpreted by the CM, e.g. if an image has to be verified using a
- NV counter, then the value of the counter to compare with can only be
- provided by the platform.
-
-#. Export a custom IPM if a proprietary image format is being used (described
- later).
-
-Authentication Module (AM)
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-It is responsible for:
-
-#. Providing the necessary abstraction mechanisms to describe a CoT. Amongst
- other things, the authentication and image parsing methods must be specified
- by the PP in the CoT.
-
-#. Verifying the CoT passed by GEN by utilising functionality exported by the
- PP, IPM and CM.
-
-#. Tracking which images have been verified. In case an image is a part of
- multiple CoTs then it should be verified only once e.g. the Trusted World
- Key Certificate in the TBBR-Client spec. contains information to verify
- SCP_BL2, BL31, BL32 each of which have a separate CoT. (This
- responsibility has not been described in this document but should be
- trivial to implement).
-
-#. Reusing memory meant for a data image to verify authentication images e.g.
- in the CoT described in Diagram 2, each certificate can be loaded and
- verified in the memory reserved by the platform for the BL31 image. By the
- time BL31 (the data image) is loaded, all information to authenticate it
- will have been extracted from the parent image i.e. BL31 content
- certificate. It is assumed that the size of an authentication image will
- never exceed the size of a data image. It should be possible to verify this
- at build time using asserts.
-
-Cryptographic Module (CM)
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The CM is responsible for providing an API to:
-
-#. Verify a digital signature.
-#. Verify a hash.
-
-The CM does not include any cryptography related code, but it relies on an
-external library to perform the cryptographic operations. A Crypto-Library (CL)
-linking the CM and the external library must be implemented. The following
-functions must be provided by the CL:
-
-.. code:: c
-
- void (*init)(void);
- int (*verify_signature)(void *data_ptr, unsigned int data_len,
- void *sig_ptr, unsigned int sig_len,
- void *sig_alg, unsigned int sig_alg_len,
- void *pk_ptr, unsigned int pk_len);
- int (*verify_hash)(void *data_ptr, unsigned int data_len,
- void *digest_info_ptr, unsigned int digest_info_len);
-
-These functions are registered in the CM using the macro:
-
-.. code:: c
-
- REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash);
-
-``_name`` must be a string containing the name of the CL. This name is used for
-debugging purposes.
-
-Image Parser Module (IPM)
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The IPM is responsible for:
-
-#. Checking the integrity of each image loaded by the IO framework.
-#. Extracting parameters used for authenticating an image based upon a
- description provided by the platform in the CoT descriptor.
-
-Images may have different formats (for example, authentication images could be
-x509v3 certificates, signed ELF files or any other platform specific format).
-The IPM allows to register an Image Parser Library (IPL) for every image format
-used in the CoT. This library must implement the specific methods to parse the
-image. The IPM obtains the image format from the CoT and calls the right IPL to
-check the image integrity and extract the authentication parameters.
-
-See Section "Describing the image parsing methods" for more details about the
-mechanism the IPM provides to define and register IPLs.
-
-Authentication methods
-~~~~~~~~~~~~~~~~~~~~~~
-
-The AM supports the following authentication methods:
-
-#. Hash
-#. Digital signature
-
-The platform may specify these methods in the CoT in case it decides to define
-a custom CoT instead of reusing a predefined one.
-
-If a data image uses multiple methods, then all the methods must be a part of
-the same CoT. The number and type of parameters are method specific. These
-parameters should be obtained from the parent image using the IPM.
-
-#. Hash
-
- Parameters:
-
- #. A pointer to data to hash
- #. Length of the data
- #. A pointer to the hash
- #. Length of the hash
-
- The hash will be represented by the DER encoding of the following ASN.1
- type:
-
- ::
-
- DigestInfo ::= SEQUENCE {
- digestAlgorithm DigestAlgorithmIdentifier,
- digest Digest
- }
-
- This ASN.1 structure makes it possible to remove any assumption about the
- type of hash algorithm used as this information accompanies the hash. This
- should allow the Cryptography Library (CL) to support multiple hash
- algorithm implementations.
-
-#. Digital Signature
-
- Parameters:
-
- #. A pointer to data to sign
- #. Length of the data
- #. Public Key Algorithm
- #. Public Key value
- #. Digital Signature Algorithm
- #. Digital Signature value
-
- The Public Key parameters will be represented by the DER encoding of the
- following ASN.1 type:
-
- ::
-
- SubjectPublicKeyInfo ::= SEQUENCE {
- algorithm AlgorithmIdentifier{PUBLIC-KEY,{PublicKeyAlgorithms}},
- subjectPublicKey BIT STRING }
-
- The Digital Signature Algorithm will be represented by the DER encoding of
- the following ASN.1 types.
-
- ::
-
- AlgorithmIdentifier {ALGORITHM:IOSet } ::= SEQUENCE {
- algorithm ALGORITHM.&id({IOSet}),
- parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL
- }
-
- The digital signature will be represented by:
-
- ::
-
- signature ::= BIT STRING
-
-The authentication framework will use the image descriptor to extract all the
-information related to authentication.
-
-Specifying a Chain of Trust
----------------------------
-
-A CoT can be described as a set of image descriptors linked together in a
-particular order. The order dictates the sequence in which they must be
-verified. Each image has a set of properties which allow the AM to verify it.
-These properties are described below.
-
-The PP is responsible for defining a single or multiple CoTs for a data image.
-Unless otherwise specified, the data structures described in the following
-sections are populated by the PP statically.
-
-Describing the image parsing methods
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The parsing method refers to the format of a particular image. For example, an
-authentication image that represents a certificate could be in the X.509v3
-format. A data image that represents a boot loader stage could be in raw binary
-or ELF format. The IPM supports three parsing methods. An image has to use one
-of the three methods described below. An IPL is responsible for interpreting a
-single parsing method. There has to be one IPL for every method used by the
-platform.
-
-#. Raw format: This format is effectively a nop as an image using this method
- is treated as being in raw binary format e.g. boot loader images used by
- TF-A. This method should only be used by data images.
-
-#. X509V3 method: This method uses industry standards like X.509 to represent
- PKI certificates (authentication images). It is expected that open source
- libraries will be available which can be used to parse an image represented
- by this method. Such libraries can be used to write the corresponding IPL
- e.g. the X.509 parsing library code in mbed TLS.
-
-#. Platform defined method: This method caters for platform specific
- proprietary standards to represent authentication or data images. For
- example, The signature of a data image could be appended to the data image
- raw binary. A header could be prepended to the combined blob to specify the
- extents of each component. The platform will have to implement the
- corresponding IPL to interpret such a format.
-
-The following enum can be used to define these three methods.
-
-.. code:: c
-
- typedef enum img_type_enum {
- IMG_RAW, /* Binary image */
- IMG_PLAT, /* Platform specific format */
- IMG_CERT, /* X509v3 certificate */
- IMG_MAX_TYPES,
- } img_type_t;
-
-An IPL must provide functions with the following prototypes:
-
-.. code:: c
-
- void init(void);
- int check_integrity(void *img, unsigned int img_len);
- int get_auth_param(const auth_param_type_desc_t *type_desc,
- void *img, unsigned int img_len,
- void **param, unsigned int *param_len);
-
-An IPL for each type must be registered using the following macro:
-
-::
-
- REGISTER_IMG_PARSER_LIB(_type, _name, _init, _check_int, _get_param)
-
-- ``_type``: one of the types described above.
-- ``_name``: a string containing the IPL name for debugging purposes.
-- ``_init``: initialization function pointer.
-- ``_check_int``: check image integrity function pointer.
-- ``_get_param``: extract authentication parameter function pointer.
-
-The ``init()`` function will be used to initialize the IPL.
-
-The ``check_integrity()`` function is passed a pointer to the memory where the
-image has been loaded by the IO framework and the image length. It should ensure
-that the image is in the format corresponding to the parsing method and has not
-been tampered with. For example, RFC-2459 describes a validation sequence for an
-X.509 certificate.
-
-The ``get_auth_param()`` function is passed a parameter descriptor containing
-information about the parameter (``type_desc`` and ``cookie``) to identify and
-extract the data corresponding to that parameter from an image. This data will
-be used to verify either the current or the next image in the CoT sequence.
-
-Each image in the CoT will specify the parsing method it uses. This information
-will be used by the IPM to find the right parser descriptor for the image.
-
-Describing the authentication method(s)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-As part of the CoT, each image has to specify one or more authentication methods
-which will be used to verify it. As described in the Section "Authentication
-methods", there are three methods supported by the AM.
-
-.. code:: c
-
- typedef enum {
- AUTH_METHOD_NONE,
- AUTH_METHOD_HASH,
- AUTH_METHOD_SIG,
- AUTH_METHOD_NUM
- } auth_method_type_t;
-
-The AM defines the type of each parameter used by an authentication method. It
-uses this information to:
-
-#. Specify to the ``get_auth_param()`` function exported by the IPM, which
- parameter should be extracted from an image.
-
-#. Correctly marshall the parameters while calling the verification function
- exported by the CM and PP.
-
-#. Extract authentication parameters from a parent image in order to verify a
- child image e.g. to verify the certificate image, the public key has to be
- obtained from the parent image.
-
-.. code:: c
-
- typedef enum {
- AUTH_PARAM_NONE,
- AUTH_PARAM_RAW_DATA, /* Raw image data */
- AUTH_PARAM_SIG, /* The image signature */
- AUTH_PARAM_SIG_ALG, /* The image signature algorithm */
- AUTH_PARAM_HASH, /* A hash (including the algorithm) */
- AUTH_PARAM_PUB_KEY, /* A public key */
- } auth_param_type_t;
-
-The AM defines the following structure to identify an authentication parameter
-required to verify an image.
-
-.. code:: c
-
- typedef struct auth_param_type_desc_s {
- auth_param_type_t type;
- void *cookie;
- } auth_param_type_desc_t;
-
-``cookie`` is used by the platform to specify additional information to the IPM
-which enables it to uniquely identify the parameter that should be extracted
-from an image. For example, the hash of a BL3x image in its corresponding
-content certificate is stored in an X509v3 custom extension field. An extension
-field can only be identified using an OID. In this case, the ``cookie`` could
-contain the pointer to the OID defined by the platform for the hash extension
-field while the ``type`` field could be set to ``AUTH_PARAM_HASH``. A value of 0 for
-the ``cookie`` field means that it is not used.
-
-For each method, the AM defines a structure with the parameters required to
-verify the image.
-
-.. code:: c
-
- /*
- * Parameters for authentication by hash matching
- */
- typedef struct auth_method_param_hash_s {
- auth_param_type_desc_t *data; /* Data to hash */
- auth_param_type_desc_t *hash; /* Hash to match with */
- } auth_method_param_hash_t;
-
- /*
- * Parameters for authentication by signature
- */
- typedef struct auth_method_param_sig_s {
- auth_param_type_desc_t *pk; /* Public key */
- auth_param_type_desc_t *sig; /* Signature to check */
- auth_param_type_desc_t *alg; /* Signature algorithm */
- auth_param_type_desc_t *tbs; /* Data signed */
- } auth_method_param_sig_t;
-
-The AM defines the following structure to describe an authentication method for
-verifying an image
-
-.. code:: c
-
- /*
- * Authentication method descriptor
- */
- typedef struct auth_method_desc_s {
- auth_method_type_t type;
- union {
- auth_method_param_hash_t hash;
- auth_method_param_sig_t sig;
- } param;
- } auth_method_desc_t;
-
-Using the method type specified in the ``type`` field, the AM finds out what field
-needs to access within the ``param`` union.
-
-Storing Authentication parameters
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A parameter described by ``auth_param_type_desc_t`` to verify an image could be
-obtained from either the image itself or its parent image. The memory allocated
-for loading the parent image will be reused for loading the child image. Hence
-parameters which are obtained from the parent for verifying a child image need
-to have memory allocated for them separately where they can be stored. This
-memory must be statically allocated by the platform port.
-
-The AM defines the following structure to store the data corresponding to an
-authentication parameter.
-
-.. code:: c
-
- typedef struct auth_param_data_desc_s {
- void *auth_param_ptr;
- unsigned int auth_param_len;
- } auth_param_data_desc_t;
-
-The ``auth_param_ptr`` field is initialized by the platform. The ``auth_param_len``
-field is used to specify the length of the data in the memory.
-
-For parameters that can be obtained from the child image itself, the IPM is
-responsible for populating the ``auth_param_ptr`` and ``auth_param_len`` fields
-while executing the ``img_get_auth_param()`` function.
-
-The AM defines the following structure to enable an image to describe the
-parameters that should be extracted from it and used to verify the next image
-(child) in a CoT.
-
-.. code:: c
-
- typedef struct auth_param_desc_s {
- auth_param_type_desc_t type_desc;
- auth_param_data_desc_t data;
- } auth_param_desc_t;
-
-Describing an image in a CoT
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-An image in a CoT is a consolidation of the following aspects of a CoT described
-above.
-
-#. A unique identifier specified by the platform which allows the IO framework
- to locate the image in a FIP and load it in the memory reserved for the data
- image in the CoT.
-
-#. A parsing method which is used by the AM to find the appropriate IPM.
-
-#. Authentication methods and their parameters as described in the previous
- section. These are used to verify the current image.
-
-#. Parameters which are used to verify the next image in the current CoT. These
- parameters are specified only by authentication images and can be extracted
- from the current image once it has been verified.
-
-The following data structure describes an image in a CoT.
-
-.. code:: c
-
- typedef struct auth_img_desc_s {
- unsigned int img_id;
- const struct auth_img_desc_s *parent;
- img_type_t img_type;
- const auth_method_desc_t *const img_auth_methods;
- const auth_param_desc_t *const authenticated_data;
- } auth_img_desc_t;
-
-A CoT is defined as an array of pointers to ``auth_image_desc_t`` structures
-linked together by the ``parent`` field. Those nodes with no parent must be
-authenticated using the ROTPK stored in the platform.
-
-Implementation example
-----------------------
-
-This section is a detailed guide explaining a trusted boot implementation using
-the authentication framework. This example corresponds to the Applicative
-Functional Mode (AFM) as specified in the TBBR-Client document. It is
-recommended to read this guide along with the source code.
-
-The TBBR CoT
-~~~~~~~~~~~~
-
-The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of
-an array of pointers to image descriptors and it is registered in the framework
-using the macro ``REGISTER_COT(cot_desc)``, where 'cot_desc' must be the name
-of the array (passing a pointer or any other type of indirection will cause the
-registration process to fail).
-
-The number of images participating in the boot process depends on the CoT.
-There is, however, a minimum set of images that are mandatory in TF-A and thus
-all CoTs must present:
-
-- ``BL2``
-- ``SCP_BL2`` (platform specific)
-- ``BL31``
-- ``BL32`` (optional)
-- ``BL33``
-
-The TBBR specifies the additional certificates that must accompany these images
-for a proper authentication. Details about the TBBR CoT may be found in the
-`Trusted Board Boot`_ document.
-
-Following the `Platform Porting Guide`_, a platform must provide unique
-identifiers for all the images and certificates that will be loaded during the
-boot process. If a platform is using the TBBR as a reference for trusted boot,
-these identifiers can be obtained from ``include/common/tbbr/tbbr_img_def.h``.
-Arm platforms include this file in ``include/plat/arm/common/arm_def.h``. Other
-platforms may also include this file or provide their own identifiers.
-
-**Important**: the authentication module uses these identifiers to index the
-CoT array, so the descriptors location in the array must match the identifiers.
-
-Each image descriptor must specify:
-
-- ``img_id``: the corresponding image unique identifier defined by the platform.
-- ``img_type``: the image parser module uses the image type to call the proper
- parsing library to check the image integrity and extract the required
- authentication parameters. Three types of images are currently supported:
-
- - ``IMG_RAW``: image is a raw binary. No parsing functions are available,
- other than reading the whole image.
- - ``IMG_PLAT``: image format is platform specific. The platform may use this
- type for custom images not directly supported by the authentication
- framework.
- - ``IMG_CERT``: image is an x509v3 certificate.
-
-- ``parent``: pointer to the parent image descriptor. The parent will contain
- the information required to authenticate the current image. If the parent
- is NULL, the authentication parameters will be obtained from the platform
- (i.e. the BL2 and Trusted Key certificates are signed with the ROT private
- key, whose public part is stored in the platform).
-- ``img_auth_methods``: this points to an array which defines the
- authentication methods that must be checked to consider an image
- authenticated. Each method consists of a type and a list of parameter
- descriptors. A parameter descriptor consists of a type and a cookie which
- will point to specific information required to extract that parameter from
- the image (i.e. if the parameter is stored in an x509v3 extension, the
- cookie will point to the extension OID). Depending on the method type, a
- different number of parameters must be specified. This pointer should not be
- NULL.
- Supported methods are:
-
- - ``AUTH_METHOD_HASH``: the hash of the image must match the hash extracted
- from the parent image. The following parameter descriptors must be
- specified:
-
- - ``data``: data to be hashed (obtained from current image)
- - ``hash``: reference hash (obtained from parent image)
-
- - ``AUTH_METHOD_SIG``: the image (usually a certificate) must be signed with
- the private key whose public part is extracted from the parent image (or
- the platform if the parent is NULL). The following parameter descriptors
- must be specified:
-
- - ``pk``: the public key (obtained from parent image)
- - ``sig``: the digital signature (obtained from current image)
- - ``alg``: the signature algorithm used (obtained from current image)
- - ``data``: the data to be signed (obtained from current image)
-
-- ``authenticated_data``: this array pointer indicates what authentication
- parameters must be extracted from an image once it has been authenticated.
- Each parameter consists of a parameter descriptor and the buffer
- address/size to store the parameter. The CoT is responsible for allocating
- the required memory to store the parameters. This pointer may be NULL.
-
-In the ``tbbr_cot.c`` file, a set of buffers are allocated to store the parameters
-extracted from the certificates. In the case of the TBBR CoT, these parameters
-are hashes and public keys. In DER format, an RSA-2048 public key requires 294
-bytes, and a hash requires 51 bytes. Depending on the CoT and the authentication
-process, some of the buffers may be reused at different stages during the boot.
-
-Next in that file, the parameter descriptors are defined. These descriptors will
-be used to extract the parameter data from the corresponding image.
-
-Example: the BL31 Chain of Trust
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Four image descriptors form the BL31 Chain of Trust:
-
-.. code:: c
-
- static const auth_img_desc_t trusted_key_cert = {
- .img_id = TRUSTED_KEY_CERT_ID,
- .img_type = IMG_CERT,
- .parent = NULL,
- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
- [0] = {
- .type = AUTH_METHOD_SIG,
- .param.sig = {
- .pk = &subject_pk,
- .sig = &sig,
- .alg = &sig_alg,
- .data = &raw_data
- }
- },
- [1] = {
- .type = AUTH_METHOD_NV_CTR,
- .param.nv_ctr = {
- .cert_nv_ctr = &trusted_nv_ctr,
- .plat_nv_ctr = &trusted_nv_ctr
- }
- }
- },
- .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
- [0] = {
- .type_desc = &trusted_world_pk,
- .data = {
- .ptr = (void *)trusted_world_pk_buf,
- .len = (unsigned int)PK_DER_LEN
- }
- },
- [1] = {
- .type_desc = &non_trusted_world_pk,
- .data = {
- .ptr = (void *)non_trusted_world_pk_buf,
- .len = (unsigned int)PK_DER_LEN
- }
- }
- }
- };
- static const auth_img_desc_t soc_fw_key_cert = {
- .img_id = SOC_FW_KEY_CERT_ID,
- .img_type = IMG_CERT,
- .parent = &trusted_key_cert,
- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
- [0] = {
- .type = AUTH_METHOD_SIG,
- .param.sig = {
- .pk = &trusted_world_pk,
- .sig = &sig,
- .alg = &sig_alg,
- .data = &raw_data
- }
- },
- [1] = {
- .type = AUTH_METHOD_NV_CTR,
- .param.nv_ctr = {
- .cert_nv_ctr = &trusted_nv_ctr,
- .plat_nv_ctr = &trusted_nv_ctr
- }
- }
- },
- .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
- [0] = {
- .type_desc = &soc_fw_content_pk,
- .data = {
- .ptr = (void *)content_pk_buf,
- .len = (unsigned int)PK_DER_LEN
- }
- }
- }
- };
- static const auth_img_desc_t soc_fw_content_cert = {
- .img_id = SOC_FW_CONTENT_CERT_ID,
- .img_type = IMG_CERT,
- .parent = &soc_fw_key_cert,
- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
- [0] = {
- .type = AUTH_METHOD_SIG,
- .param.sig = {
- .pk = &soc_fw_content_pk,
- .sig = &sig,
- .alg = &sig_alg,
- .data = &raw_data
- }
- },
- [1] = {
- .type = AUTH_METHOD_NV_CTR,
- .param.nv_ctr = {
- .cert_nv_ctr = &trusted_nv_ctr,
- .plat_nv_ctr = &trusted_nv_ctr
- }
- }
- },
- .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
- [0] = {
- .type_desc = &soc_fw_hash,
- .data = {
- .ptr = (void *)soc_fw_hash_buf,
- .len = (unsigned int)HASH_DER_LEN
- }
- },
- [1] = {
- .type_desc = &soc_fw_config_hash,
- .data = {
- .ptr = (void *)soc_fw_config_hash_buf,
- .len = (unsigned int)HASH_DER_LEN
- }
- }
- }
- };
- static const auth_img_desc_t bl31_image = {
- .img_id = BL31_IMAGE_ID,
- .img_type = IMG_RAW,
- .parent = &soc_fw_content_cert,
- .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
- [0] = {
- .type = AUTH_METHOD_HASH,
- .param.hash = {
- .data = &raw_data,
- .hash = &soc_fw_hash
- }
- }
- }
- };
-
-The **Trusted Key certificate** is signed with the ROT private key and contains
-the Trusted World public key and the Non-Trusted World public key as x509v3
-extensions. This must be specified in the image descriptor using the
-``img_auth_methods`` and ``authenticated_data`` arrays, respectively.
-
-The Trusted Key certificate is authenticated by checking its digital signature
-using the ROTPK. Four parameters are required to check a signature: the public
-key, the algorithm, the signature and the data that has been signed. Therefore,
-four parameter descriptors must be specified with the authentication method:
-
-- ``subject_pk``: parameter descriptor of type ``AUTH_PARAM_PUB_KEY``. This type
- is used to extract a public key from the parent image. If the cookie is an
- OID, the key is extracted from the corresponding x509v3 extension. If the
- cookie is NULL, the subject public key is retrieved. In this case, because
- the parent image is NULL, the public key is obtained from the platform
- (this key will be the ROTPK).
-- ``sig``: parameter descriptor of type ``AUTH_PARAM_SIG``. It is used to extract
- the signature from the certificate.
-- ``sig_alg``: parameter descriptor of type ``AUTH_PARAM_SIG``. It is used to
- extract the signature algorithm from the certificate.
-- ``raw_data``: parameter descriptor of type ``AUTH_PARAM_RAW_DATA``. It is used
- to extract the data to be signed from the certificate.
-
-Once the signature has been checked and the certificate authenticated, the
-Trusted World public key needs to be extracted from the certificate. A new entry
-is created in the ``authenticated_data`` array for that purpose. In that entry,
-the corresponding parameter descriptor must be specified along with the buffer
-address to store the parameter value. In this case, the ``tz_world_pk`` descriptor
-is used to extract the public key from an x509v3 extension with OID
-``TRUSTED_WORLD_PK_OID``. The BL31 key certificate will use this descriptor as
-parameter in the signature authentication method. The key is stored in the
-``plat_tz_world_pk_buf`` buffer.
-
-The **BL31 Key certificate** is authenticated by checking its digital signature
-using the Trusted World public key obtained previously from the Trusted Key
-certificate. In the image descriptor, we specify a single authentication method
-by signature whose public key is the ``tz_world_pk``. Once this certificate has
-been authenticated, we have to extract the BL31 public key, stored in the
-extension specified by ``bl31_content_pk``. This key will be copied to the
-``plat_content_pk`` buffer.
-
-The **BL31 certificate** is authenticated by checking its digital signature
-using the BL31 public key obtained previously from the BL31 Key certificate.
-We specify the authentication method using ``bl31_content_pk`` as public key.
-After authentication, we need to extract the BL31 hash, stored in the extension
-specified by ``bl31_hash``. This hash will be copied to the ``plat_bl31_hash_buf``
-buffer.
-
-The **BL31 image** is authenticated by calculating its hash and matching it
-with the hash obtained from the BL31 certificate. The image descriptor contains
-a single authentication method by hash. The parameters to the hash method are
-the reference hash, ``bl31_hash``, and the data to be hashed. In this case, it is
-the whole image, so we specify ``raw_data``.
-
-The image parser library
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The image parser module relies on libraries to check the image integrity and
-extract the authentication parameters. The number and type of parser libraries
-depend on the images used in the CoT. Raw images do not need a library, so
-only an x509v3 library is required for the TBBR CoT.
-
-Arm platforms will use an x509v3 library based on mbed TLS. This library may be
-found in ``drivers/auth/mbedtls/mbedtls_x509_parser.c``. It exports three
-functions:
-
-.. code:: c
-
- void init(void);
- int check_integrity(void *img, unsigned int img_len);
- int get_auth_param(const auth_param_type_desc_t *type_desc,
- void *img, unsigned int img_len,
- void **param, unsigned int *param_len);
-
-The library is registered in the framework using the macro
-``REGISTER_IMG_PARSER_LIB()``. Each time the image parser module needs to access
-an image of type ``IMG_CERT``, it will call the corresponding function exported
-in this file.
-
-The build system must be updated to include the corresponding library and
-mbed TLS sources. Arm platforms use the ``arm_common.mk`` file to pull the
-sources.
-
-The cryptographic library
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The cryptographic module relies on a library to perform the required operations,
-i.e. verify a hash or a digital signature. Arm platforms will use a library
-based on mbed TLS, which can be found in
-``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the
-authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports
-three functions:
-
-.. code:: c
-
- void init(void);
- int verify_signature(void *data_ptr, unsigned int data_len,
- void *sig_ptr, unsigned int sig_len,
- void *sig_alg, unsigned int sig_alg_len,
- void *pk_ptr, unsigned int pk_len);
- int verify_hash(void *data_ptr, unsigned int data_len,
- void *digest_info_ptr, unsigned int digest_info_len);
-
-The mbedTLS library algorithm support is configured by the
-``TF_MBEDTLS_KEY_ALG`` variable which can take in 3 values: `rsa`, `ecdsa` or
-`rsa+ecdsa`. This variable allows the Makefile to include the corresponding
-sources in the build for the various algorithms. Setting the variable to
-`rsa+ecdsa` enables support for both rsa and ecdsa algorithms in the mbedTLS
-library.
-
-Note: If code size is a concern, the build option ``MBEDTLS_SHA256_SMALLER`` can
-be defined in the platform Makefile. It will make mbed TLS use an implementation
-of SHA-256 with smaller memory footprint (~1.5 KB less) but slower (~30%).
-
---------------
-
-*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _Trusted Board Boot: ./trusted-board-boot.rst
-.. _Platform Porting Guide: ./porting-guide.rst
-.. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
*Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.*
.. _SDEI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
-.. _PSCI Integration Guide: psci-lib-integration-guide.rst
+.. _PSCI Integration Guide: ./getting_started/psci-lib-integration-guide.rst
.. _Developer Certificate of Origin: ../dco.txt
-.. _Contribution Guide: ../contributing.rst
-.. _Authentication framework: auth-framework.rst
-.. _Firmware Update: firmware-update.rst
-.. _TF-A Reset Design: reset-design.rst
-.. _Power Domain Topology Design: psci-pd-tree.rst
+.. _Contribution Guide: ./contributing.rst
+.. _Authentication framework: ./design/auth-framework.rst
+.. _Firmware Update: ./design/firmware-update.rst
+.. _TF-A Reset Design: ./design/reset-design.rst
+.. _Power Domain Topology Design: ./design/psci-pd-tree.rst
.. _TF-A wiki on GitHub: https://github.com/ARM-software/arm-trusted-firmware/wiki/ARM-Trusted-Firmware-Image-Terminology
-.. _Authentication Framework: auth-framework.rst
-.. _OP-TEE Dispatcher: optee-dispatcher.rst
+.. _Authentication Framework: ./design/auth-framework.rst
+.. _OP-TEE Dispatcher: ./spd/optee-dispatcher.rst
.. _tf-issue#501: https://github.com/ARM-software/tf-issues/issues/501
.. _PR#1002: https://github.com/ARM-software/arm-trusted-firmware/pull/1002#issuecomment-312650193
+++ /dev/null
-Trusted Firmware-A Coding Guidelines
-====================================
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-The following sections contain TF coding guidelines. They are continually
-evolving and should not be considered "set in stone". Feel free to question them
-and provide feedback.
-
-Some of the guidelines may also apply to other codebases.
-
-**Note:** the existing TF codebase does not necessarily comply with all the
-below guidelines but the intent is for it to do so eventually.
-
-Checkpatch overrides
---------------------
-
-Some checkpatch warnings in the TF codebase are deliberately ignored. These
-include:
-
-- ``**WARNING: line over 80 characters**``: Although the codebase should
- generally conform to the 80 character limit this is overly restrictive in some
- cases.
-
-- ``**WARNING: Use of volatile is usually wrong``: see
- `Why the “volatile” type class should not be used`_ . Although this document
- contains some very useful information, there are several legimate uses of the
- volatile keyword within the TF codebase.
-
-Headers and inclusion
----------------------
-
-Header guards
-^^^^^^^^^^^^^
-
-For a header file called "some_driver.h" the style used by the Trusted Firmware
-is:
-
-.. code:: c
-
- #ifndef SOME_DRIVER_H
- #define SOME_DRIVER_H
-
- <header content>
-
- #endif /* SOME_DRIVER_H */
-
-Include statement ordering
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-All header files that are included by a source file must use the following,
-grouped ordering. This is to improve readability (by making it easier to quickly
-read through the list of headers) and maintainability.
-
-#. *System* includes: Header files from the standard *C* library, such as
- ``stddef.h`` and ``string.h``.
-
-#. *Project* includes: Header files under the ``include/`` directory within TF
- are *project* includes.
-
-#. *Platform* includes: Header files relating to a single, specific platform,
- and which are located under the ``plat/<platform_name>`` directory within TF,
- are *platform* includes.
-
-Within each group, ``#include`` statements must be in alphabetical order,
-taking both the file and directory names into account.
-
-Groups must be separated by a single blank line for clarity.
-
-The example below illustrates the ordering rules using some contrived header
-file names; this type of name reuse should be otherwise avoided.
-
-.. code:: c
-
- #include <string.h>
-
- #include <a_dir/example/a_header.h>
- #include <a_dir/example/b_header.h>
- #include <a_dir/test/a_header.h>
- #include <b_dir/example/a_header.h>
-
- #include "./a_header.h"
-
-Include statement variants
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Two variants of the ``#include`` directive are acceptable in the TF codebase.
-Correct use of the two styles improves readability by suggesting the location
-of the included header and reducing ambiguity in cases where generic and
-platform-specific headers share a name.
-
-For header files that are in the same directory as the source file that is
-including them, use the ``"..."`` variant.
-
-For header files that are **not** in the same directory as the source file that
-is including them, use the ``<...>`` variant.
-
-Example (bl1_fwu.c):
-
-.. code:: c
-
- #include <assert.h>
- #include <errno.h>
- #include <string.h>
-
- #include "bl1_private.h"
-
-Platform include paths
-^^^^^^^^^^^^^^^^^^^^^^
-
-Platforms are allowed to add more include paths to be passed to the compiler.
-The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
-particular for the file ``platform_def.h``.
-
-Example:
-
-.. code:: c
-
- PLAT_INCLUDES += -Iinclude/plat/myplat/include
-
-Types and typedefs
-------------------
-
-Use of built-in *C* and *libc* data types
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The TF codebase should be kept as portable as possible, especially since both
-64-bit and 32-bit platforms are supported. To help with this, the following data
-type usage guidelines should be followed:
-
-- Where possible, use the built-in *C* data types for variable storage (for
- example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
- types. Most code is typically only concerned with the minimum size of the
- data stored, which the built-in *C* types guarantee.
-
-- Avoid using the exact-size standard *C99* types in general (for example,
- ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
- compiler from making optimizations. There are legitimate uses for them,
- for example to represent data of a known structure. When using them in struct
- definitions, consider how padding in the struct will work across architectures.
- For example, extra padding may be introduced in AArch32 systems if a struct
- member crosses a 32-bit boundary.
-
-- Use ``int`` as the default integer type - it's likely to be the fastest on all
- systems. Also this can be assumed to be 32-bit as a consequence of the
- `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
- Standard for the Arm 64-bit Architecture`_ .
-
-- Avoid use of ``short`` as this may end up being slower than ``int`` in some
- systems. If a variable must be exactly 16-bit, use ``int16_t`` or
- ``uint16_t``.
-
-- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
- that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
- at least 64-bit, use ``long long``.
-
-- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
-
-- Use ``unsigned`` for integers that can never be negative (counts,
- indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
- rules (10.X), where signed and unsigned types are considered different
- essential types. Choosing the correct type will aid this. MISRA static
- analysers will pick up any implicit signed/unsigned conversions that may lead
- to unexpected behaviour.
-
-- For pointer types:
-
- - If an argument in a function declaration is pointing to a known type then
- simply use a pointer to that type (for example: ``struct my_struct *``).
-
- - If a variable (including an argument in a function declaration) is pointing
- to a general, memory-mapped address, an array of pointers or another
- structure that is likely to require pointer arithmetic then use
- ``uintptr_t``. This will reduce the amount of casting required in the code.
- Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
- may work but is less portable.
-
- - For other pointer arguments in a function declaration, use ``void *``. This
- includes pointers to types that are abstracted away from the known API and
- pointers to arbitrary data. This allows the calling function to pass a
- pointer argument to the function without any explicit casting (the cast to
- ``void *`` is implicit). The function implementation can then do the
- appropriate casting to a specific type.
-
- - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
-
-- Use ``size_t`` when storing the ``sizeof()`` something.
-
-- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
- can also return an error code; the signed type allows for a negative return
- code in case of error. This practice should be used sparingly.
-
-- Use ``u_register_t`` when it's important to store the contents of a register
- in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a
- standard *C99* type but is widely available in libc implementations,
- including the FreeBSD version included with the TF codebase. Where possible,
- cast the variable to a more appropriate type before interpreting the data. For
- example, the following struct in ``ep_info.h`` could use this type to minimize
- the storage required for the set of registers:
-
-.. code:: c
-
- typedef struct aapcs64_params {
- u_register_t arg0;
- u_register_t arg1;
- u_register_t arg2;
- u_register_t arg3;
- u_register_t arg4;
- u_register_t arg5;
- u_register_t arg6;
- u_register_t arg7;
- } aapcs64_params_t;
-
-If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
-unsigned integer on all systems, cast it to ``unsigned int``.
-
-These guidelines should be updated if additional types are needed.
-
-Avoid anonymous typedefs of structs/enums in headers
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-For example, the following definition:
-
-.. code:: c
-
- typedef struct {
- int arg1;
- int arg2;
- } my_struct_t;
-
-
-is better written as:
-
-.. code:: c
-
- struct my_struct {
- int arg1;
- int arg2;
- };
-
-This allows function declarations in other header files that depend on the
-struct/enum to forward declare the struct/enum instead of including the
-entire header:
-
-.. code:: c
-
- #include <my_struct.h>
- void my_func(my_struct_t *arg);
-
-instead of:
-
-.. code:: c
-
- struct my_struct;
- void my_func(struct my_struct *arg);
-
-Some TF definitions use both a struct/enum name **and** a typedef name. This
-is discouraged for new definitions as it makes it difficult for TF to comply
-with MISRA rule 8.3, which states that "All declarations of an object or
-function shall use the same names and type qualifiers".
-
-The Linux coding standards also discourage new typedefs and checkpatch emits
-a warning for this.
-
-Existing typedefs will be retained for compatibility.
-
-Error handling and robustness
------------------------------
-
-Using CASSERT to check for compile time data errors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Where possible, use the ``CASSERT`` macro to check the validity of data known at
-compile time instead of checking validity at runtime, to avoid unnecessary
-runtime code.
-
-For example, this can be used to check that the assembler's and compiler's views
-of the size of an array is the same.
-
-.. code:: c
-
- #include <cassert.h>
-
- define MY_STRUCT_SIZE 8 /* Used by assembler source files */
-
- struct my_struct {
- uint32_t arg1;
- uint32_t arg2;
- };
-
- CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
-
-
-If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
-emit an error like this:
-
-.. code:: c
-
- my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
-
-
-Using assert() to check for programming errors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
-treated as a tightly integrated package; the image builder should be aware of
-and responsible for all functionality within the image, even if code within that
-image is provided by multiple entities. This allows us to be more aggressive in
-interpreting invalid state or bad function arguments as programming errors using
-``assert()``, including arguments passed across platform porting interfaces.
-This is in contrast to code in a Linux environment, which is less tightly
-integrated and may attempt to be more defensive by passing the error back up the
-call stack.
-
-Where possible, badly written TF code should fail early using ``assert()``. This
-helps reduce the amount of untested conditional code. By default these
-statements are not compiled into release builds, although this can be overridden
-using the ``ENABLE_ASSERTIONS`` build flag.
-
-Examples:
-
-- Bad argument supplied to library function
-- Bad argument provided by platform porting function
-- Internal secure world image state is inconsistent
-
-
-Handling integration errors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Each secure world image may be provided by a different entity (for example, a
-Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
-image and the OEM/SoC vendor may provide the other images).
-
-An image may contain bugs that are only visible when the images are integrated.
-The system integrator may not even have access to the debug variants of all the
-images in order to check if asserts are firing. For example, the release variant
-of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
-an integration error should _not_ consider this a programming error, and should
-always take action, even in release builds.
-
-If an integration error is considered non-critical it should be treated as a
-recoverable error. If the error is considered critical it should be treated as
-an unexpected unrecoverable error.
-
-Handling recoverable errors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The secure world **must not** crash when supplied with bad data from an external
-source. For example, data from the normal world or a hardware device. Similarly,
-the secure world **must not** crash if it detects a non-critical problem within
-itself or the system. It must make every effort to recover from the problem by
-emitting a ``WARN`` message, performing any necessary error handling and
-continuing.
-
-Examples:
-
-- Secure world receives SMC from normal world with bad arguments.
-- Secure world receives SMC from normal world at an unexpected time.
-- BL31 receives SMC from BL32 with bad arguments.
-- BL31 receives SMC from BL32 at unexpected time.
-- Secure world receives recoverable error from hardware device. Retrying the
- operation may help here.
-- Non-critical secure world service is not functioning correctly.
-- BL31 SPD discovers minor configuration problem with corresponding SP.
-
-Handling unrecoverable errors
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In some cases it may not be possible for the secure world to recover from an
-error. This situation should be handled in one of the following ways:
-
-1. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
- call ``panic()``. This will end up calling the platform-specific function
- ``plat_panic_handler()``.
-2. If the unrecoverable error is expected to occur in certain circumstances,
- then emit an ``ERROR`` message and call the platform-specific function
- ``plat_error_handler()``.
-
-Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
-and ``plat_error_handler`` in the same way (for example, by waiting for a secure
-watchdog to time-out or by invoking an interface on the platform's power
-controller to reset the platform). However, ``plat_error_handler`` may take
-additional action for some errors (for example, it may set a flag so the
-platform resets into a different mode). Also, ``plat_panic_handler()`` may
-implement additional debug functionality (for example, invoking a hardware
-breakpoint).
-
-Examples of unexpected unrecoverable errors:
-
-- BL32 receives an unexpected SMC response from BL31 that it is unable to
- recover from.
-- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
- Trusted OS, which is critical for platform operation.
-- Secure world discovers that a critical hardware device is an unexpected and
- unrecoverable state.
-- Secure world receives an unexpected and unrecoverable error from a critical
- hardware device.
-- Secure world discovers that it is running on unsupported hardware.
-
-Examples of expected unrecoverable errors:
-
-- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
-- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
-- Secure world continuously receives recoverable errors from a hardware device
- but is unable to proceed without a valid response.
-
-Handling critical unresponsiveness
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If the secure world is waiting for a response from an external source (for
-example, the normal world or a hardware device) which is critical for continued
-operation, it must not wait indefinitely. It must have a mechanism (for example,
-a secure watchdog) for resetting itself and/or the external source to prevent
-the system from executing in this state indefinitely.
-
-Examples:
-
-- BL1 is waiting for the normal world to raise an SMC to proceed to the next
- stage of the secure firmware update process.
-- A Trusted OS is waiting for a response from a proxy in the normal world that
- is critical for continued operation.
-- Secure world is waiting for a hardware response that is critical for continued
- operation.
-
-Security considerations
------------------------
-
-Part of the security of a platform is handling errors correctly, as described in
-the previous section. There are several other security considerations covered in
-this section.
-
-Do not leak secrets to the normal world
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The secure world **must not** leak secrets to the normal world, for example in
-response to an SMC.
-
-Handling Denial of Service attacks
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The secure world **should never** crash or become unusable due to receiving too
-many normal world requests (a *Denial of Service* or *DoS* attack). It should
-have a mechanism for throttling or ignoring normal world requests.
-
-Performance considerations
---------------------------
-
-Avoid printf and use logging macros
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
-which wrap ``tf_log`` and which allow the logging call to be compiled-out
-depending on the ``make`` command. Use these macros to avoid print statements
-being compiled unconditionally into the binary.
-
-Each logging macro has a numerical log level:
-
-.. code:: c
-
- #define LOG_LEVEL_NONE 0
- #define LOG_LEVEL_ERROR 10
- #define LOG_LEVEL_NOTICE 20
- #define LOG_LEVEL_WARNING 30
- #define LOG_LEVEL_INFO 40
- #define LOG_LEVEL_VERBOSE 50
-
-
-By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
-be compiled into debug builds and all statements with a log level
-``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
-overridden from the command line or by the platform makefile (although it may be
-necessary to clean the build directory first). For example, to enable
-``VERBOSE`` logging on FVP:
-
-``make PLAT=fvp LOG_LEVEL=50 all``
-
-Use const data where possible
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-For example, the following code:
-
-.. code:: c
-
- struct my_struct {
- int arg1;
- int arg2;
- };
-
- void init(struct my_struct *ptr);
-
- void main(void)
- {
- struct my_struct x;
- x.arg1 = 1;
- x.arg2 = 2;
- init(&x);
- }
-
-is better written as:
-
-.. code:: c
-
- struct my_struct {
- int arg1;
- int arg2;
- };
-
- void init(const struct my_struct *ptr);
-
- void main(void)
- {
- const struct my_struct x = { 1, 2 };
- init(&x);
- }
-
-This allows the linker to put the data in a read-only data section instead of a
-writeable data section, which may result in a smaller and faster binary. Note
-that this may require dependent functions (``init()`` in the above example) to
-have ``const`` arguments, assuming they don't need to modify the data.
-
-Library and driver code
------------------------
-
-TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
-reusable interface to other code, potentially even to code outside of TF.
-
-In some systems drivers must conform to a specific driver framework to provide
-services to the rest of the system. TF has no driver framework and the
-distinction between a driver and library is somewhat subjective.
-
-A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
-interfaces with hardware via a memory mapped interface.
-
-Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
-provide a general purpose API to that specific hardware. Other drivers (for
-example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
-provide a specific hardware implementation of a more abstract library API. In
-the latter case there may potentially be multiple drivers for the same hardware
-device.
-
-Neither libraries nor drivers should depend on platform-specific code. If they
-require platform-specific data (for example, a base address) to operate then
-they should provide an initialization function that takes the platform-specific
-data as arguments.
-
-TF common code (under ``common/`` and ``include/common/``) is code that is re-used
-by other generic (non-platform-specific) TF code. It is effectively internal
-library code.
-
-.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
-.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
-.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
--- /dev/null
+Arm SiP Service
+===============
+
+This document enumerates and describes the Arm SiP (Silicon Provider) services.
+
+SiP services are non-standard, platform-specific services offered by the silicon
+implementer or platform provider. They are accessed via ``SMC`` ("SMC calls")
+instruction executed from Exception Levels below EL3. SMC calls for SiP
+services:
+
+- Follow `SMC Calling Convention`_;
+- Use SMC function IDs that fall in the SiP range, which are ``0xc2000000`` -
+ ``0xc200ffff`` for 64-bit calls, and ``0x82000000`` - ``0x8200ffff`` for 32-bit
+ calls.
+
+The Arm SiP implementation offers the following services:
+
+- Performance Measurement Framework (PMF)
+- Execution State Switching service
+
+Source definitions for Arm SiP service are located in the ``arm_sip_svc.h`` header
+file.
+
+Performance Measurement Framework (PMF)
+---------------------------------------
+
+The `Performance Measurement Framework`_
+allows callers to retrieve timestamps captured at various paths in TF-A
+execution. It's described in detail in `Firmware Design document`_.
+
+Execution State Switching service
+---------------------------------
+
+Execution State Switching service provides a mechanism for a non-secure lower
+Exception Level (either EL2, or NS EL1 if EL2 isn't implemented) to request to
+switch its execution state (a.k.a. Register Width), either from AArch64 to
+AArch32, or from AArch32 to AArch64, for the calling CPU. This service is only
+available when Trusted Firmware-A (TF-A) is built for AArch64 (i.e. when build
+option ``ARCH`` is set to ``aarch64``).
+
+``ARM_SIP_SVC_EXE_STATE_SWITCH``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t Function ID
+ uint32_t PC hi
+ uint32_t PC lo
+ uint32_t Cookie hi
+ uint32_t Cookie lo
+
+ Return:
+ uint32_t
+
+The function ID parameter must be ``0x82000020``. It uniquely identifies the
+Execution State Switching service being requested.
+
+The parameters *PC hi* and *PC lo* defines upper and lower words, respectively,
+of the entry point (physical address) at which execution should start, after
+Execution State has been switched. When calling from AArch64, *PC hi* must be 0.
+
+When execution starts at the supplied entry point after Execution State has been
+switched, the parameters *Cookie hi* and *Cookie lo* are passed in CPU registers
+0 and 1, respectively. When calling from AArch64, *Cookie hi* must be 0.
+
+This call can only be made on the primary CPU, before any secondaries were
+brought up with ``CPU_ON`` PSCI call. Otherwise, the call will always fail.
+
+The effect of switching execution state is as if the Exception Level were
+entered for the first time, following power on. This means CPU registers that
+have a defined reset value by the Architecture will assume that value. Other
+registers should not be expected to hold their values before the call was made.
+CPU endianness, however, is preserved from the previous execution state. Note
+that this switches the execution state of the calling CPU only. This is not a
+substitute for PSCI ``SYSTEM_RESET``.
+
+The service may return the following error codes:
+
+- ``STATE_SW_E_PARAM``: If any of the parameters were deemed invalid for
+ a specific request.
+- ``STATE_SW_E_DENIED``: If the call is not successful, or when TF-A is
+ built for AArch32.
+
+If the call is successful, the caller wouldn't observe the SMC returning.
+Instead, execution starts at the supplied entry point, with the CPU registers 0
+and 1 populated with the supplied *Cookie hi* and *Cookie lo* values,
+respectively.
+
+--------------
+
+*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+.. _Performance Measurement Framework: ./firmware-design.rst#user-content-performance-measurement-framework
+.. _Firmware Design document: ./firmware-design.rst
--- /dev/null
+Exception Handling Framework in Trusted Firmware-A
+==================================================
+
+
+
+
+.. contents::
+ :depth: 2
+
+.. |EHF| replace:: Exception Handling Framework
+.. |TF-A| replace:: Trusted Firmware-A
+
+This document describes various aspects of handling exceptions by Runtime
+Firmware (BL31) that are targeted at EL3, other than SMCs. The |EHF| takes care
+of the following exceptions when targeted at EL3:
+
+- Interrupts
+- Synchronous External Aborts
+- Asynchronous External Aborts
+
+|TF-A|'s handling of synchronous ``SMC`` exceptions raised from lower ELs is
+described in the `Firmware Design document`__. However, the |EHF| changes the
+semantics of `interrupt handling`__ and `synchronous exceptions`__ other than
+SMCs.
+
+.. __: firmware-design.rst#handling-an-smc
+.. __: `Interrupt handling`_
+.. __: `Effect on SMC calls`_
+
+The |EHF| is selected by setting the build option ``EL3_EXCEPTION_HANDLING`` to
+``1``, and is only available for AArch64 systems.
+
+Introduction
+------------
+
+Through various control bits in the ``SCR_EL3`` register, the Arm architecture
+allows for asynchronous exceptions to be routed to EL3. As described in the
+`Interrupt Framework Design`_ document, depending on the chosen interrupt
+routing model, TF-A appropriately sets the ``FIQ`` and ``IRQ`` bits of
+``SCR_EL3`` register to effect this routing. For most use cases, other than for
+the purpose of facilitating context switch between Normal and Secure worlds,
+FIQs and IRQs routed to EL3 are not required to be handled in EL3.
+
+However, the evolving system and standards landscape demands that various
+exceptions are targeted at and handled in EL3. For instance:
+
+- Starting with ARMv8.2 architecture extension, many RAS features have been
+ introduced to the Arm architecture. With RAS features implemented, various
+ components of the system may use one of the asynchronous exceptions to signal
+ error conditions to PEs. These error conditions are of critical nature, and
+ it's imperative that corrective or remedial actions are taken at the earliest
+ opportunity. Therefore, a *Firmware-first Handling* approach is generally
+ followed in response to RAS events in the system.
+
+- The Arm `SDEI specification`_ defines interfaces through which Normal world
+ interacts with the Runtime Firmware in order to request notification of
+ system events. The SDEI specification requires that these events are notified
+ even when the Normal world executes with the exceptions masked. This too
+ implies that firmware-first handling is required, where the events are first
+ received by the EL3 firmware, and then dispatched to Normal world through
+ purely software mechanism.
+
+For |TF-A|, firmware-first handling means that asynchronous exceptions are
+suitably routed to EL3, and the Runtime Firmware (BL31) is extended to include
+software components that are capable of handling those exceptions that target
+EL3. These components—referred to as *dispatchers* [#spd]_ in general—may
+choose to:
+
+.. _delegation-use-cases:
+
+- Receive and handle exceptions entirely in EL3, meaning the exceptions
+ handling terminates in EL3.
+
+- Receive exceptions, but handle part of the exception in EL3, and delegate the
+ rest of the handling to a dedicated software stack running at lower Secure
+ ELs. In this scheme, the handling spans various secure ELs.
+
+- Receive exceptions, but handle part of the exception in EL3, and delegate
+ processing of the error to dedicated software stack running at lower secure
+ ELs (as above); additionally, the Normal world may also be required to
+ participate in the handling, or be notified of such events (for example, as
+ an SDEI event). In this scheme, exception handling potentially and maximally
+ spans all ELs in both Secure and Normal worlds.
+
+On any given system, all of the above handling models may be employed
+independently depending on platform choice and the nature of the exception
+received.
+
+.. [#spd] Not to be confused with `Secure Payload Dispatcher`__, which is an
+ EL3 component that operates in EL3 on behalf of Secure OS.
+
+.. __: firmware-design.rst#secure-el1-payloads-and-dispatchers
+
+The role of Exception Handling Framework
+----------------------------------------
+
+Corollary to the use cases cited above, the primary role of the |EHF| is to
+facilitate firmware-first handling of exceptions on Arm systems. The |EHF| thus
+enables multiple exception dispatchers in runtime firmware to co-exist, register
+for, and handle exceptions targeted at EL3. This section outlines the basics,
+and the rest of this document expands the various aspects of the |EHF|.
+
+In order to arbitrate exception handling among dispatchers, the |EHF| operation
+is based on a priority scheme. This priority scheme is closely tied to how the
+Arm GIC architecture defines it, although it's applied to non-interrupt
+exceptions too (SErrors, for example).
+
+The platform is required to `partition`__ the Secure priority space into
+priority levels as applicable for the Secure software stack. It then assigns the
+dispatchers to one or more priority levels. The dispatchers then register
+handlers for the priority levels at runtime. A dispatcher can register handlers
+for more than one priority level.
+
+.. __: `Partitioning priority levels`_
+
+
+.. _ehf-figure:
+
+.. image:: ../draw.io/ehf.svg
+
+A priority level is *active* when a handler at that priority level is currently
+executing in EL3, or has delegated the execution to a lower EL. For interrupts,
+this is implicit when an interrupt is targeted and acknowledged at EL3, and the
+priority of the acknowledged interrupt is used to match its registered handler.
+The priority level is likewise implicitly deactivated when the interrupt
+handling concludes by EOIing the interrupt.
+
+Non-interrupt exceptions (SErrors, for example) don't have a notion of priority.
+In order for the priority arbitration to work, the |EHF| provides APIs in order
+for these non-interrupt exceptions to assume a priority, and to interwork with
+interrupts. Dispatchers handling such exceptions must therefore explicitly
+activate and deactivate the respective priority level as and when they're
+handled or delegated.
+
+Because priority activation and deactivation for interrupt handling is implicit
+and involves GIC priority masking, it's impossible for a lower priority
+interrupt to preempt a higher priority one. By extension, this means that a
+lower priority dispatcher cannot preempt a higher-priority one. Priority
+activation and deactivation for non-interrupt exceptions, however, has to be
+explicit. The |EHF| therefore disallows for lower priority level to be activated
+whilst a higher priority level is active, and would result in a panic.
+Likewise, a panic would result if it's attempted to deactivate a lower priority
+level when a higher priority level is active.
+
+In essence, priority level activation and deactivation conceptually works like a
+stack—priority levels stack up in strictly increasing fashion, and need to be
+unstacked in strictly the reverse order. For interrupts, the GIC ensures this is
+the case; for non-interrupts, the |EHF| monitors and asserts this. See
+`Transition of priority levels`_.
+
+Interrupt handling
+------------------
+
+The |EHF| is a client of *Interrupt Management Framework*, and registers the
+top-level handler for interrupts that target EL3, as described in the `Interrupt
+Framework Design`_ document. This has the following implications.
+
+- On GICv3 systems, when executing in S-EL1, pending Non-secure interrupts of
+ sufficient priority are signalled as FIQs, and therefore will be routed to
+ EL3. As a result, S-EL1 software cannot expect to handle Non-secure
+ interrupts at S-EL1. Essentially, this deprecates the routing mode described
+ as `CSS=0, TEL3=0`__.
+
+ .. __: interrupt-framework-design.rst#el3-interrupts
+
+ In order for S-EL1 software to handle Non-secure interrupts while having
+ |EHF| enabled, the dispatcher must adopt a model where Non-secure interrupts
+ are received at EL3, but are then `synchronously`__ handled over to S-EL1.
+
+ .. __: interrupt-framework-design.rst#secure-payload
+
+- On GICv2 systems, it's required that the build option ``GICV2_G0_FOR_EL3`` is
+ set to ``1`` so that *Group 0* interrupts target EL3.
+
+- While executing in Secure world, |EHF| sets GIC Priority Mask Register to the
+ lowest Secure priority. This means that no Non-secure interrupts can preempt
+ Secure execution. See `Effect on SMC calls`_ for more details.
+
+As mentioned above, with |EHF|, the platform is required to partition *Group 0*
+interrupts into distinct priority levels. A dispatcher that chooses to receive
+interrupts can then *own* one or more priority levels, and register interrupt
+handlers for them. A given priority level can be assigned to only one handler. A
+dispatcher may register more than one priority level.
+
+Dispatchers are assigned interrupt priority levels in two steps:
+
+Partitioning priority levels
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Interrupts are associated to dispatchers by way of grouping and assigning
+interrupts to a priority level. In other words, all interrupts that are to
+target a particular dispatcher should fall in a particular priority level. For
+priority assignment:
+
+- Of the 8 bits of priority that Arm GIC architecture permits, bit 7 must be 0
+ (secure space).
+
+- Depending on the number of dispatchers to support, the platform must choose
+ to use the top *n* of the 7 remaining bits to identify and assign interrupts
+ to individual dispatchers. Choosing *n* bits supports up to 2\ :sup:`n`
+ distinct dispatchers. For example, by choosing 2 additional bits (i.e., bits
+ 6 and 5), the platform can partition into 4 secure priority ranges: ``0x0``,
+ ``0x20``, ``0x40``, and ``0x60``. See `Interrupt handling example`_.
+
+Note:
+
+ The Arm GIC architecture requires that a GIC implementation that supports two
+ security states must implement at least 32 priority levels; i.e., at least 5
+ upper bits of the 8 bits are writeable. In the scheme described above, when
+ choosing *n* bits for priority range assignment, the platform must ensure
+ that at least ``n+1`` top bits of GIC priority are writeable.
+
+The priority thus assigned to an interrupt is also used to determine the
+priority of delegated execution in lower ELs. Delegated execution in lower EL is
+associated with a priority level chosen with ``ehf_activate_priority()`` API
+(described `later`__). The chosen priority level also determines the interrupts
+masked while executing in a lower EL, therefore controls preemption of delegated
+execution.
+
+.. __: `ehf-apis`_
+
+The platform expresses the chosen priority levels by declaring an array of
+priority level descriptors. Each entry in the array is of type
+``ehf_pri_desc_t``, and declares a priority level, and shall be populated by the
+``EHF_PRI_DESC()`` macro.
+
+Note:
+
+ The macro ``EHF_PRI_DESC()`` installs the descriptors in the array at a
+ computed index, and not necessarily where the macro is placed in the array.
+ The size of the array might therefore be larger than what it appears to be.
+ The ``ARRAY_SIZE()`` macro therefore should be used to determine the size of
+ array.
+
+Finally, this array of descriptors is exposed to |EHF| via the
+``EHF_REGISTER_PRIORITIES()`` macro.
+
+Refer to the `Interrupt handling example`_ for usage. See also: `Interrupt
+Prioritisation Considerations`_.
+
+Programming priority
+~~~~~~~~~~~~~~~~~~~~
+
+The text in `Partitioning priority levels`_ only describes how the platform
+expresses the required levels of priority. It however doesn't choose interrupts
+nor program the required priority in GIC.
+
+The `Firmware Design guide`__ explains methods for configuring secure
+interrupts. |EHF| requires the platform to enumerate interrupt properties (as
+opposed to just numbers) of Secure interrupts. The priority of secure interrupts
+must match that as determined in the `Partitioning priority levels`_ section above.
+
+.. __: firmware-design.rst#configuring-secure-interrupts
+
+See `Limitations`_, and also refer to `Interrupt handling example`_ for
+illustration.
+
+Registering handler
+-------------------
+
+Dispatchers register handlers for their priority levels through the following
+API:
+
+.. code:: c
+
+ int ehf_register_priority_handler(int pri, ehf_handler_t handler)
+
+The API takes two arguments:
+
+- The priority level for which the handler is being registered;
+
+- The handler to be registered. The handler must be aligned to 4 bytes.
+
+If a dispatcher owns more than one priority levels, it has to call the API for
+each of them.
+
+The API will succeed, and return ``0``, only if:
+
+- There exists a descriptor with the priority level requested.
+
+- There are no handlers already registered by a previous call to the API.
+
+Otherwise, the API returns ``-1``.
+
+The interrupt handler should have the following signature:
+
+.. code:: c
+
+ typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle,
+ void *cookie);
+
+The parameters are as obtained from the top-level `EL3 interrupt handler`__.
+
+.. __: interrupt-framework-design.rst#el3-runtime-firmware
+
+The `SDEI dispatcher`__, for example, expects the platform to allocate two
+different priority levels—``PLAT_SDEI_CRITICAL_PRI``, and
+``PLAT_SDEI_NORMAL_PRI``—and registers the same handler to handle both levels.
+
+.. __: sdei.rst
+
+Interrupt handling example
+--------------------------
+
+The following annotated snippet demonstrates how a platform might choose to
+assign interrupts to fictitious dispatchers:
+
+.. code:: c
+
+ #include <common/interrupt_props.h>
+ #include <drivers/arm/gic_common.h>
+ #include <exception_mgmt.h>
+
+ ...
+
+ /*
+ * This platform uses 2 bits for interrupt association. In total, 3 upper
+ * bits are in use.
+ *
+ * 7 6 5 3 0
+ * .-.-.-.----------.
+ * |0|b|b| ..0.. |
+ * '-'-'-'----------'
+ */
+ #define PLAT_PRI_BITS 2
+
+ /* Priorities for individual dispatchers */
+ #define DISP0_PRIO 0x00 /* Not used */
+ #define DISP1_PRIO 0x20
+ #define DISP2_PRIO 0x40
+ #define DISP3_PRIO 0x60
+
+ /* Install priority level descriptors for each dispatcher */
+ ehf_pri_desc_t plat_exceptions[] = {
+ EHF_PRI_DESC(PLAT_PRI_BITS, DISP1_PRIO),
+ EHF_PRI_DESC(PLAT_PRI_BITS, DISP2_PRIO),
+ EHF_PRI_DESC(PLAT_PRI_BITS, DISP3_PRIO),
+ };
+
+ /* Expose priority descriptors to Exception Handling Framework */
+ EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions),
+ PLAT_PRI_BITS);
+
+ ...
+
+ /* List interrupt properties for GIC driver. All interrupts target EL3 */
+ const interrupt_prop_t plat_interrupts[] = {
+ /* Dispatcher 1 owns interrupts d1_0 and d1_1, so assigns priority DISP1_PRIO */
+ INTR_PROP_DESC(d1_0, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(d1_1, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+
+ /* Dispatcher 2 owns interrupts d2_0 and d2_1, so assigns priority DISP2_PRIO */
+ INTR_PROP_DESC(d2_0, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(d2_1, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+
+ /* Dispatcher 3 owns interrupts d3_0 and d3_1, so assigns priority DISP3_PRIO */
+ INTR_PROP_DESC(d3_0, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+ INTR_PROP_DESC(d3_1, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
+ };
+
+ ...
+
+ /* Dispatcher 1 registers its handler */
+ ehf_register_priority_handler(DISP1_PRIO, disp1_handler);
+
+ /* Dispatcher 2 registers its handler */
+ ehf_register_priority_handler(DISP2_PRIO, disp2_handler);
+
+ /* Dispatcher 3 registers its handler */
+ ehf_register_priority_handler(DISP3_PRIO, disp3_handler);
+
+ ...
+
+See also the `Build-time flow`_ and the `Run-time flow`_.
+
+Activating and Deactivating priorities
+--------------------------------------
+
+A priority level is said to be *active* when an exception of that priority is
+being handled: for interrupts, this is implied when the interrupt is
+acknowledged; for non-interrupt exceptions, such as SErrors or `SDEI explicit
+dispatches`__, this has to be done via calling ``ehf_activate_priority()``. See
+`Run-time flow`_.
+
+.. __: sdei.rst#explicit-dispatch-of-events
+
+Conversely, when the dispatcher has reached a logical resolution for the cause
+of the exception, the corresponding priority level ought to be deactivated. As
+above, for interrupts, this is implied when the interrupt is EOId in the GIC;
+for other exceptions, this has to be done via calling
+``ehf_deactivate_priority()``.
+
+Thanks to `different provisions`__ for exception delegation, there are
+potentially more than one work flow for deactivation:
+
+.. __: `delegation-use-cases`_
+
+.. _deactivation workflows:
+
+- The dispatcher has addressed the cause of the exception, and decided to take
+ no further action. In this case, the dispatcher's handler deactivates the
+ priority level before returning to the |EHF|. Runtime firmware, upon exit
+ through an ``ERET``, resumes execution before the interrupt occurred.
+
+- The dispatcher has to delegate the execution to lower ELs, and the cause of
+ the exception can be considered resolved only when the lower EL returns
+ signals complete (via an ``SMC``) at a future point in time. The following
+ sequence ensues:
+
+ #. The dispatcher calls ``setjmp()`` to setup a jump point, and arranges to
+ enter a lower EL upon the next ``ERET``.
+
+ #. Through the ensuing ``ERET`` from runtime firmware, execution is delegated
+ to a lower EL.
+
+ #. The lower EL completes its execution, and signals completion via an
+ ``SMC``.
+
+ #. The ``SMC`` is handled by the same dispatcher that handled the exception
+ previously. Noticing the conclusion of exception handling, the dispatcher
+ does ``longjmp()`` to resume beyond the previous jump point.
+
+As mentioned above, the |EHF| provides the following APIs for activating and
+deactivating interrupt:
+
+.. _ehf-apis:
+
+- ``ehf_activate_priority()`` activates the supplied priority level, but only
+ if the current active priority is higher than the given one; otherwise
+ panics. Also, to prevent interruption by physical interrupts of lower
+ priority, the |EHF| programs the *Priority Mask Register* corresponding to
+ the PE to the priority being activated. Dispatchers typically only need to
+ call this when handling exceptions other than interrupts, and it needs to
+ delegate execution to a lower EL at a desired priority level.
+
+- ``ehf_deactivate_priority()`` deactivates a given priority, but only if the
+ current active priority is equal to the given one; otherwise panics. |EHF|
+ also restores the *Priority Mask Register* corresponding to the PE to the
+ priority before the call to ``ehf_activate_priority()``. Dispatchers
+ typically only need to call this after handling exceptions other than
+ interrupts.
+
+The calling of APIs are subject to allowed `transitions`__. See also the
+`Run-time flow`_.
+
+.. __: `Transition of priority levels`_
+
+Transition of priority levels
+-----------------------------
+
+The |EHF| APIs ``ehf_activate_priority()`` and ``ehf_deactivate_priority()`` can
+be called to transition the current priority level on a PE. A given sequence of
+calls to these APIs are subject to the following conditions:
+
+- For activation, the |EHF| only allows for the priority to increase (i.e.
+ numeric value decreases);
+
+- For deactivation, the |EHF| only allows for the priority to decrease (i.e.
+ numeric value increases). Additionally, the priority being deactivated is
+ required to be the current priority.
+
+If these are violated, a panic will result.
+
+Effect on SMC calls
+-------------------
+
+In general, Secure execution is regarded as more important than Non-secure
+execution. As discussed elsewhere in this document, EL3 execution, and any
+delegated execution thereafter, has the effect of raising GIC's priority
+mask—either implicitly by acknowledging Secure interrupts, or when dispatchers
+call ``ehf_activate_priority()``. As a result, Non-secure interrupts cannot
+preempt any Secure execution.
+
+SMCs from Non-secure world are synchronous exceptions, and are mechanisms for
+Non-secure world to request Secure services. They're broadly classified as
+*Fast* or *Yielding* (see `SMCCC`__).
+
+.. __: `http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html`
+
+- *Fast* SMCs are atomic from the caller's point of view. I.e., they return
+ to the caller only when the Secure world has finished serving the request.
+ Any Non-secure interrupts that become pending meanwhile cannot preempt Secure
+ execution.
+
+- *Yielding* SMCs carry the semantics of a preemptible, lower-priority request.
+ A pending Non-secure interrupt can preempt Secure execution handling a
+ Yielding SMC. I.e., the caller might observe a Yielding SMC returning when
+ either:
+
+ #. Secure world completes the request, and the caller would find ``SMC_OK``
+ as the return code.
+
+ #. A Non-secure interrupt preempts Secure execution. Non-secure interrupt is
+ handled, and Non-secure execution resumes after ``SMC`` instruction.
+
+ The dispatcher handling a Yielding SMC must provide a different return code
+ to the Non-secure caller to distinguish the latter case. This return code,
+ however, is not standardised (unlike ``SMC_UNKNOWN`` or ``SMC_OK``, for
+ example), so will vary across dispatchers that handle the request.
+
+For the latter case above, dispatchers before |EHF| expect Non-secure interrupts
+to be taken to S-EL1 [#irq]_, so would get a chance to populate the designated
+preempted error code before yielding to Non-secure world.
+
+The introduction of |EHF| changes the behaviour as described in `Interrupt
+handling`_.
+
+When |EHF| is enabled, in order to allow Non-secure interrupts to preempt
+Yielding SMC handling, the dispatcher must call ``ehf_allow_ns_preemption()``
+API. The API takes one argument, the error code to be returned to the Non-secure
+world upon getting preempted.
+
+.. [#irq] In case of GICv2, Non-secure interrupts while in S-EL1 were signalled
+ as IRQs, and in case of GICv3, FIQs.
+
+Build-time flow
+---------------
+
+Please refer to the `figure`__ above.
+
+.. __: `ehf-figure`_
+
+The build-time flow involves the following steps:
+
+#. Platform assigns priorities by installing priority level descriptors for
+ individual dispatchers, as described in `Partitioning priority levels`_.
+
+#. Platform provides interrupt properties to GIC driver, as described in
+ `Programming priority`_.
+
+#. Dispatcher calling ``ehf_register_priority_handler()`` to register an
+ interrupt handler.
+
+Also refer to the `Interrupt handling example`_.
+
+Run-time flow
+-------------
+
+.. _interrupt-flow:
+
+The following is an example flow for interrupts:
+
+#. The GIC driver, during initialization, iterates through the platform-supplied
+ interrupt properties (see `Programming priority`_), and configures the
+ interrupts. This programs the appropriate priority and group (Group 0) on
+ interrupts belonging to different dispatchers.
+
+#. The |EHF|, during its initialisation, registers a top-level interrupt handler
+ with the `Interrupt Management Framework`__ for EL3 interrupts. This also
+ results in setting the routing bits in ``SCR_EL3``.
+
+ .. __: interrupt-framework-design.rst#el3-runtime-firmware
+
+#. When an interrupt belonging to a dispatcher fires, GIC raises an EL3/Group 0
+ interrupt, and is taken to EL3.
+
+#. The top-level EL3 interrupt handler executes. The handler acknowledges the
+ interrupt, reads its *Running Priority*, and from that, determines the
+ dispatcher handler.
+
+#. The |EHF| programs the *Priority Mask Register* of the PE to the priority of
+ the interrupt received.
+
+#. The |EHF| marks that priority level *active*, and jumps to the dispatcher
+ handler.
+
+#. Once the dispatcher handler finishes its job, it has to immediately
+ *deactivate* the priority level before returning to the |EHF|. See
+ `deactivation workflows`_.
+
+.. _non-interrupt-flow:
+
+The following is an example flow for exceptions that targets EL3 other than
+interrupt:
+
+#. The platform provides handlers for the specific kind of exception.
+
+#. The exception arrives, and the corresponding handler is executed.
+
+#. The handler calls ``ehf_activate_priority()`` to activate the required
+ priority level. This also has the effect of raising GIC priority mask, thus
+ preventing interrupts of lower priority from preempting the handling. The
+ handler may choose to do the handling entirely in EL3 or delegate to a lower
+ EL.
+
+#. Once exception handling concludes, the handler calls
+ ``ehf_deactivate_priority()`` to deactivate the priority level activated
+ earlier. This also has the effect of lowering GIC priority mask to what it
+ was before.
+
+Interrupt Prioritisation Considerations
+---------------------------------------
+
+The GIC priority scheme, by design, prioritises Secure interrupts over Normal
+world ones. The platform further assigns relative priorities amongst Secure
+dispatchers through |EHF|.
+
+As mentioned in `Partitioning priority levels`_, interrupts targeting distinct
+dispatchers fall in distinct priority levels. Because they're routed via the
+GIC, interrupt delivery to the PE is subject to GIC prioritisation rules. In
+particular, when an interrupt is being handled by the PE (i.e., the interrupt is
+in *Active* state), only interrupts of higher priority are signalled to the PE,
+even if interrupts of same or lower priority are pending. This has the side
+effect of one dispatcher being starved of interrupts by virtue of another
+dispatcher handling its (higher priority) interrupts.
+
+The |EHF| doesn't enforce a particular prioritisation policy, but the platform
+should carefully consider the assignment of priorities to dispatchers integrated
+into runtime firmware. The platform should sensibly delineate priority to
+various dispatchers according to their nature. In particular, dispatchers of
+critical nature (RAS, for example) should be assigned higher priority than
+others (SDEI, for example); and within SDEI, Critical priority SDEI should be
+assigned higher priority than Normal ones.
+
+Limitations
+-----------
+
+The |EHF| has the following limitations:
+
+- Although there could be up to 128 Secure dispatchers supported by the GIC
+ priority scheme, the size of descriptor array exposed with
+ ``EHF_REGISTER_PRIORITIES()`` macro is currently limited to 32. This serves most
+ expected use cases. This may be expanded in the future, should use cases
+ demand so.
+
+- The platform must ensure that the priority assigned to the dispatcher in the
+ exception descriptor and the programmed priority of interrupts handled by the
+ dispatcher match. The |EHF| cannot verify that this has been followed.
+
+----
+
+*Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _Interrupt Framework Design: interrupt-framework-design.rst
+.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
--- /dev/null
+Trusted Firmware-A - Firmware Update design guide
+=================================================
+
+
+
+
+.. contents::
+
+--------------
+
+Introduction
+------------
+
+This document describes the design of the Firmware Update (FWU) feature, which
+enables authenticated firmware to update firmware images from external
+interfaces such as USB, UART, SD-eMMC, NAND, NOR or Ethernet to SoC Non-Volatile
+memories such as NAND Flash, LPPDR2-NVM or any memory determined by the
+platform. This feature functions even when the current firmware in the system
+is corrupt or missing; it therefore may be used as a recovery mode. It may also
+be complemented by other, higher level firmware update software.
+
+FWU implements a specific part of the Trusted Board Boot Requirements (TBBR)
+specification, Arm DEN0006C-1. It should be used in conjunction with the
+`Trusted Board Boot`_ design document, which describes the image authentication
+parts of the Trusted Firmware-A (TF-A) TBBR implementation.
+
+Scope
+~~~~~
+
+This document describes the secure world FWU design. It is beyond its scope to
+describe how normal world FWU images should operate. To implement normal world
+FWU images, please refer to the "Non-Trusted Firmware Updater" requirements in
+the TBBR.
+
+FWU Overview
+------------
+
+The FWU boot flow is primarily mediated by BL1. Since BL1 executes in ROM, and
+it is usually desirable to minimize the amount of ROM code, the design allows
+some parts of FWU to be implemented in other secure and normal world images.
+Platform code may choose which parts are implemented in which images but the
+general expectation is:
+
+- BL1 handles:
+
+ - Detection and initiation of the FWU boot flow.
+ - Copying images from non-secure to secure memory
+ - FWU image authentication
+ - Context switching between the normal and secure world during the FWU
+ process.
+
+- Other secure world FWU images handle platform initialization required by
+ the FWU process.
+- Normal world FWU images handle loading of firmware images from external
+ interfaces to non-secure memory.
+
+The primary requirements of the FWU feature are:
+
+#. Export a BL1 SMC interface to interoperate with other FWU images executing
+ at other Exception Levels.
+#. Export a platform interface to provide FWU common code with the information
+ it needs, and to enable platform specific FWU functionality. See the
+ `Porting Guide`_ for details of this interface.
+
+TF-A uses abbreviated image terminology for FWU images like for other TF-A
+images. An overview of this terminology can be found `here`_.
+
+The following diagram shows the FWU boot flow for Arm development platforms.
+Arm CSS platforms like Juno have a System Control Processor (SCP), and these
+use all defined FWU images. Other platforms may use a subset of these.
+
+|Flow Diagram|
+
+Image Identification
+--------------------
+
+Each FWU image and certificate is identified by a unique ID, defined by the
+platform, which BL1 uses to fetch an image descriptor (``image_desc_t``) via a
+call to ``bl1_plat_get_image_desc()``. The same ID is also used to prepare the
+Chain of Trust (Refer to the `Authentication Framework Design`_
+for more information).
+
+The image descriptor includes the following information:
+
+- Executable or non-executable image. This indicates whether the normal world
+ is permitted to request execution of a secure world FWU image (after
+ authentication). Secure world certificates and non-AP images are examples
+ of non-executable images.
+- Secure or non-secure image. This indicates whether the image is
+ authenticated/executed in secure or non-secure memory.
+- Image base address and size.
+- Image entry point configuration (an ``entry_point_info_t``).
+- FWU image state.
+
+BL1 uses the FWU image descriptors to:
+
+- Validate the arguments of FWU SMCs
+- Manage the state of the FWU process
+- Initialize the execution state of the next FWU image.
+
+FWU State Machine
+-----------------
+
+BL1 maintains state for each FWU image during FWU execution. FWU images at lower
+Exception Levels raise SMCs to invoke FWU functionality in BL1, which causes
+BL1 to update its FWU image state. The BL1 image states and valid state
+transitions are shown in the diagram below. Note that secure images have a more
+complex state machine than non-secure images.
+
+|FWU state machine|
+
+The following is a brief description of the supported states:
+
+- RESET: This is the initial state of every image at the start of FWU.
+ Authentication failure also leads to this state. A secure
+ image may yield to this state if it has completed execution.
+ It can also be reached by using ``FWU_SMC_IMAGE_RESET``.
+
+- COPYING: This is the state of a secure image while BL1 is copying it
+ in blocks from non-secure to secure memory.
+
+- COPIED: This is the state of a secure image when BL1 has completed
+ copying it to secure memory.
+
+- AUTHENTICATED: This is the state of an image when BL1 has successfully
+ authenticated it.
+
+- EXECUTED: This is the state of a secure, executable image when BL1 has
+ passed execution control to it.
+
+- INTERRUPTED: This is the state of a secure, executable image after it has
+ requested BL1 to resume normal world execution.
+
+BL1 SMC Interface
+-----------------
+
+BL1_SMC_CALL_COUNT
+~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x0
+
+ Return:
+ uint32_t
+
+This SMC returns the number of SMCs supported by BL1.
+
+BL1_SMC_UID
+~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x1
+
+ Return:
+ UUID : 32 bits in each of w0-w3 (or r0-r3 for AArch32 callers)
+
+This SMC returns the 128-bit `Universally Unique Identifier`_ for the
+BL1 SMC service.
+
+BL1_SMC_VERSION
+~~~~~~~~~~~~~~~
+
+::
+
+ Argument:
+ uint32_t function ID : 0x3
+
+ Return:
+ uint32_t : Bits [31:16] Major Version
+ Bits [15:0] Minor Version
+
+This SMC returns the current version of the BL1 SMC service.
+
+BL1_SMC_RUN_IMAGE
+~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x4
+ entry_point_info_t *ep_info
+
+ Return:
+ void
+
+ Pre-conditions:
+ if (normal world caller) synchronous exception
+ if (ep_info not EL3) synchronous exception
+
+This SMC passes execution control to an EL3 image described by the provided
+``entry_point_info_t`` structure. In the normal TF-A boot flow, BL2 invokes
+this SMC for BL1 to pass execution control to BL31.
+
+FWU_SMC_IMAGE_COPY
+~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x10
+ unsigned int image_id
+ uintptr_t image_addr
+ unsigned int block_size
+ unsigned int image_size
+
+ Return:
+ int : 0 (Success)
+ : -ENOMEM
+ : -EPERM
+
+ Pre-conditions:
+ if (image_id is invalid) return -EPERM
+ if (image_id is non-secure image) return -EPERM
+ if (image_id state is not (RESET or COPYING)) return -EPERM
+ if (secure world caller) return -EPERM
+ if (image_addr + block_size overflows) return -ENOMEM
+ if (image destination address + image_size overflows) return -ENOMEM
+ if (source block is in secure memory) return -ENOMEM
+ if (source block is not mapped into BL1) return -ENOMEM
+ if (image_size > free secure memory) return -ENOMEM
+ if (image overlaps another image) return -EPERM
+
+This SMC copies the secure image indicated by ``image_id`` from non-secure memory
+to secure memory for later authentication. The image may be copied in a single
+block or multiple blocks. In either case, the total size of the image must be
+provided in ``image_size`` when invoking this SMC for the first time for each
+image; it is ignored in subsequent calls (if any) for the same image.
+
+The ``image_addr`` and ``block_size`` specify the source memory block to copy from.
+The destination address is provided by the platform code.
+
+If ``block_size`` is greater than the amount of remaining bytes to copy for this
+image then the former is truncated to the latter. The copy operation is then
+considered as complete and the FWU state machine transitions to the "COPIED"
+state. If there is still more to copy, the FWU state machine stays in or
+transitions to the COPYING state (depending on the previous state).
+
+When using multiple blocks, the source blocks do not necessarily need to be in
+contiguous memory.
+
+Once the SMC is handled, BL1 returns from exception to the normal world caller.
+
+FWU_SMC_IMAGE_AUTH
+~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x11
+ unsigned int image_id
+ uintptr_t image_addr
+ unsigned int image_size
+
+ Return:
+ int : 0 (Success)
+ : -ENOMEM
+ : -EPERM
+ : -EAUTH
+
+ Pre-conditions:
+ if (image_id is invalid) return -EPERM
+ if (secure world caller)
+ if (image_id state is not RESET) return -EPERM
+ if (image_addr/image_size is not mapped into BL1) return -ENOMEM
+ else // normal world caller
+ if (image_id is secure image)
+ if (image_id state is not COPIED) return -EPERM
+ else // image_id is non-secure image
+ if (image_id state is not RESET) return -EPERM
+ if (image_addr/image_size is in secure memory) return -ENOMEM
+ if (image_addr/image_size not mapped into BL1) return -ENOMEM
+
+This SMC authenticates the image specified by ``image_id``. If the image is in the
+RESET state, BL1 authenticates the image in place using the provided
+``image_addr`` and ``image_size``. If the image is a secure image in the COPIED
+state, BL1 authenticates the image from the secure memory that BL1 previously
+copied the image into.
+
+BL1 returns from exception to the caller. If authentication succeeds then BL1
+sets the image state to AUTHENTICATED. If authentication fails then BL1 returns
+the -EAUTH error and sets the image state back to RESET.
+
+FWU_SMC_IMAGE_EXECUTE
+~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x12
+ unsigned int image_id
+
+ Return:
+ int : 0 (Success)
+ : -EPERM
+
+ Pre-conditions:
+ if (image_id is invalid) return -EPERM
+ if (secure world caller) return -EPERM
+ if (image_id is non-secure image) return -EPERM
+ if (image_id is non-executable image) return -EPERM
+ if (image_id state is not AUTHENTICATED) return -EPERM
+
+This SMC initiates execution of a previously authenticated image specified by
+``image_id``, in the other security world to the caller. The current
+implementation only supports normal world callers initiating execution of a
+secure world image.
+
+BL1 saves the normal world caller's context, sets the secure image state to
+EXECUTED, and returns from exception to the secure image.
+
+FWU_SMC_IMAGE_RESUME
+~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x13
+ register_t image_param
+
+ Return:
+ register_t : image_param (Success)
+ : -EPERM
+
+ Pre-conditions:
+ if (normal world caller and no INTERRUPTED secure image) return -EPERM
+
+This SMC resumes execution in the other security world while there is a secure
+image in the EXECUTED/INTERRUPTED state.
+
+For normal world callers, BL1 sets the previously interrupted secure image state
+to EXECUTED. For secure world callers, BL1 sets the previously executing secure
+image state to INTERRUPTED. In either case, BL1 saves the calling world's
+context, restores the resuming world's context and returns from exception into
+the resuming world. If the call is successful then the caller provided
+``image_param`` is returned to the resumed world, otherwise an error code is
+returned to the caller.
+
+FWU_SMC_SEC_IMAGE_DONE
+~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x14
+
+ Return:
+ int : 0 (Success)
+ : -EPERM
+
+ Pre-conditions:
+ if (normal world caller) return -EPERM
+
+This SMC indicates completion of a previously executing secure image.
+
+BL1 sets the previously executing secure image state to the RESET state,
+restores the normal world context and returns from exception into the normal
+world.
+
+FWU_SMC_UPDATE_DONE
+~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x15
+ register_t client_cookie
+
+ Return:
+ N/A
+
+This SMC completes the firmware update process. BL1 calls the platform specific
+function ``bl1_plat_fwu_done``, passing the optional argument ``client_cookie`` as
+a ``void *``. The SMC does not return.
+
+FWU_SMC_IMAGE_RESET
+~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments:
+ uint32_t function ID : 0x16
+ unsigned int image_id
+
+ Return:
+ int : 0 (Success)
+ : -EPERM
+
+ Pre-conditions:
+ if (secure world caller) return -EPERM
+ if (image in EXECUTED) return -EPERM
+
+This SMC sets the state of an image to RESET and zeroes the memory used by it.
+
+This is only allowed if the image is not being executed.
+
+--------------
+
+*Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _Trusted Board Boot: ./trusted-board-boot.rst
+.. _Porting Guide: ../getting_started/porting-guide.rst
+.. _here: https://github.com/ARM-software/arm-trusted-firmware/wiki/ARM-Trusted-Firmware-Image-Terminology
+.. _Authentication Framework Design: ./auth-framework.rst
+.. _Universally Unique Identifier: https://tools.ietf.org/rfc/rfc4122.txt
+
+.. |Flow Diagram| image:: diagrams/fwu_flow.png?raw=true
+.. |FWU state machine| image:: diagrams/fwu_states.png?raw=true
--- /dev/null
+Components
+==========
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+ :numbered:
+
+ spd/index
+ arm-sip-service
+ exception-handling
+ firmware-update
+ platform-interrupt-controller-API
+ ras
+ romlib-design
+ sdei
+ secure-partition-manager-design
+ xlat-tables-lib-v2-design
--- /dev/null
+Platform Interrupt Controller API documentation
+===============================================
+
+
+
+.. contents::
+
+This document lists the optional platform interrupt controller API that
+abstracts the runtime configuration and control of interrupt controller from the
+generic code. The mandatory APIs are described in the `porting guide`__.
+
+.. __: ../getting_started/porting-guide.rst#interrupt-management-framework-in-bl31
+
+Function: unsigned int plat_ic_get_running_priority(void); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : unsigned int
+
+This API should return the priority of the interrupt the PE is currently
+servicing. This must be be called only after an interrupt has already been
+acknowledged via ``plat_ic_acknowledge_interrupt``.
+
+In the case of Arm standard platforms using GIC, the *Running Priority Register*
+is read to determine the priority of the interrupt.
+
+Function: int plat_ic_is_spi(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : int
+
+The API should return whether the interrupt ID (first parameter) is categorized
+as a Shared Peripheral Interrupt. Shared Peripheral Interrupts are typically
+associated to system-wide peripherals, and these interrupts can target any PE in
+the system.
+
+Function: int plat_ic_is_ppi(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : int
+
+The API should return whether the interrupt ID (first parameter) is categorized
+as a Private Peripheral Interrupt. Private Peripheral Interrupts are typically
+associated with peripherals that are private to each PE. Interrupts from private
+peripherals target to that PE only.
+
+Function: int plat_ic_is_sgi(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : int
+
+The API should return whether the interrupt ID (first parameter) is categorized
+as a Software Generated Interrupt. Software Generated Interrupts are raised by
+explicit programming by software, and are typically used in inter-PE
+communication. Secure SGIs are reserved for use by Secure world software.
+
+Function: unsigned int plat_ic_get_interrupt_active(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : int
+
+This API should return the *active* status of the interrupt ID specified by the
+first parameter, ``id``.
+
+In case of Arm standard platforms using GIC, the implementation of the API reads
+the GIC *Set Active Register* to read and return the active status of the
+interrupt.
+
+Function: void plat_ic_enable_interrupt(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : void
+
+This API should enable the interrupt ID specified by the first parameter,
+``id``. PEs in the system are expected to receive only enabled interrupts.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+inserts barrier to make memory updates visible before enabling interrupt, and
+then writes to GIC *Set Enable Register* to enable the interrupt.
+
+Function: void plat_ic_disable_interrupt(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : void
+
+This API should disable the interrupt ID specified by the first parameter,
+``id``. PEs in the system are not expected to receive disabled interrupts.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+writes to GIC *Clear Enable Register* to disable the interrupt, and inserts
+barrier to make memory updates visible afterwards.
+
+Function: void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Argument : unsigned int
+ Return : void
+
+This API should set the priority of the interrupt specified by first parameter
+``id`` to the value set by the second parameter ``priority``.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+writes to GIC *Priority Register* set interrupt priority.
+
+Function: int plat_ic_has_interrupt_type(unsigned int type); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : int
+
+This API should return whether the platform supports a given interrupt type. The
+parameter ``type`` shall be one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1``, or
+``INTR_TYPE_NS``.
+
+In case of Arm standard platforms using GICv3, the implementation of the API
+returns ``1`` for all interrupt types.
+
+In case of Arm standard platforms using GICv2, the API always return ``1`` for
+``INTR_TYPE_NS``. Return value for other types depends on the value of build
+option ``GICV2_G0_FOR_EL3``:
+
+- For interrupt type ``INTR_TYPE_EL3``:
+
+ - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns ``0``, indicating no support
+ for EL3 interrupts.
+
+ - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns ``1``, indicating support for
+ EL3 interrupts.
+
+- For interrupt type ``INTR_TYPE_S_EL1``:
+
+ - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns ``1``, indicating support for
+ Secure EL1 interrupts.
+
+ - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns ``0``, indicating no support
+ for Secure EL1 interrupts.
+
+Function: void plat_ic_set_interrupt_type(unsigned int id, unsigned int type); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Argument : unsigned int
+ Return : void
+
+This API should set the interrupt specified by first parameter ``id`` to the
+type specified by second parameter ``type``. The ``type`` parameter can be
+one of:
+
+- ``INTR_TYPE_NS``: interrupt is meant to be consumed by the Non-secure world.
+
+- ``INTR_TYPE_S_EL1``: interrupt is meant to be consumed by Secure EL1.
+
+- ``INTR_TYPE_EL3``: interrupt is meant to be consumed by EL3.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+writes to the GIC *Group Register* and *Group Modifier Register* (only GICv3) to
+assign the interrupt to the right group.
+
+For GICv3:
+
+- ``INTR_TYPE_NS`` maps to Group 1 interrupt.
+
+- ``INTR_TYPE_S_EL1`` maps to Secure Group 1 interrupt.
+
+- ``INTR_TYPE_EL3`` maps to Secure Group 0 interrupt.
+
+For GICv2:
+
+- ``INTR_TYPE_NS`` maps to Group 1 interrupt.
+
+- When the build option ``GICV2_G0_FOR_EL3`` is set to ``0`` (the default),
+ ``INTR_TYPE_S_EL1`` maps to Group 0. Otherwise, ``INTR_TYPE_EL3`` maps to
+ Group 0 interrupt.
+
+Function: void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Argument : u_register_t
+ Return : void
+
+This API should raise an EL3 SGI. The first parameter, ``sgi_num``, specifies
+the ID of the SGI. The second parameter, ``target``, must be the MPIDR of the
+target PE.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+inserts barrier to make memory updates visible before raising SGI, then writes
+to appropriate *SGI Register* in order to raise the EL3 SGI.
+
+Function: void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, u_register_t mpidr); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Argument : unsigned int
+ Argument : u_register_t
+ Return : void
+
+This API should set the routing mode of Share Peripheral Interrupt (SPI)
+specified by first parameter ``id`` to that specified by the second parameter
+``routing_mode``.
+
+The ``routing_mode`` parameter can be one of:
+
+- ``INTR_ROUTING_MODE_ANY`` means the interrupt can be routed to any PE in the
+ system. The ``mpidr`` parameter is ignored in this case.
+
+- ``INTR_ROUTING_MODE_PE`` means the interrupt is routed to the PE whose MPIDR
+ value is specified by the parameter ``mpidr``.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+writes to the GIC *Target Register* (GICv2) or *Route Register* (GICv3) to set
+the routing.
+
+Function: void plat_ic_set_interrupt_pending(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : void
+
+This API should set the interrupt specified by first parameter ``id`` to
+*Pending*.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+inserts barrier to make memory updates visible before setting interrupt pending,
+and writes to the GIC *Set Pending Register* to set the interrupt pending
+status.
+
+Function: void plat_ic_clear_interrupt_pending(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : void
+
+This API should clear the *Pending* status of the interrupt specified by first
+parameter ``id``.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+writes to the GIC *Clear Pending Register* to clear the interrupt pending
+status, and inserts barrier to make memory updates visible afterwards.
+
+Function: unsigned int plat_ic_set_priority_mask(unsigned int id); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : int
+
+This API should set the priority mask (first parameter) in the interrupt
+controller such that only interrupts of higher priority than the supplied one
+may be signalled to the PE. The API should return the current priority value
+that it's overwriting.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+inserts to order memory updates before updating mask, then writes to the GIC
+*Priority Mask Register*, and make sure memory updates are visible before
+potential trigger due to mask update.
+
+Function: unsigned int plat_ic_get_interrupt_id(unsigned int raw); [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : unsigned int
+
+This API should extract and return the interrupt number from the raw value
+obtained by the acknowledging the interrupt (read using
+``plat_ic_acknowledge_interrupt()``). If the interrupt ID is invalid, this API
+should return ``INTR_ID_UNAVAILABLE``.
+
+In case of Arm standard platforms using GIC, the implementation of the API
+masks out the interrupt ID field from the acknowledged value from GIC.
+
+----
+
+*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
--- /dev/null
+RAS support in Trusted Firmware-A
+=================================
+
+
+
+.. contents::
+ :depth: 2
+
+.. |EHF| replace:: Exception Handling Framework
+.. |TF-A| replace:: Trusted Firmware-A
+
+This document describes |TF-A| support for Arm Reliability, Availability, and
+Serviceability (RAS) extensions. RAS is a mandatory extension for Armv8.2 and
+later CPUs, and also an optional extension to the base Armv8.0 architecture.
+
+In conjunction with the |EHF|, support for RAS extension enables firmware-first
+paradigm for handling platform errors: exceptions resulting from errors are
+routed to and handled in EL3. Said errors are Synchronous External Abort (SEA),
+Asynchronous External Abort (signalled as SErrors), Fault Handling and Error
+Recovery interrupts. The |EHF| document mentions various `error handling
+use-cases`__.
+
+.. __: exception-handling.rst#delegation-use-cases
+
+For the description of Arm RAS extensions, Standard Error Records, and the
+precise definition of RAS terminology, please refer to the Arm Architecture
+Reference Manual. The rest of this document assumes familiarity with
+architecture and terminology.
+
+Overview
+--------
+
+As mentioned above, the RAS support in |TF-A| enables routing to and handling of
+exceptions resulting from platform errors in EL3. It allows the platform to
+define an External Abort handler, and to register RAS nodes and interrupts. RAS
+framework also provides `helpers`__ for accessing Standard Error Records as
+introduced by the RAS extensions.
+
+.. __: `Standard Error Record helpers`_
+
+The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run
+time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST`` must also
+be set ``1``.
+
+.. _ras-figure:
+
+.. image:: ../draw.io/ras.svg
+
+See more on `Engaging the RAS framework`_.
+
+Platform APIs
+-------------
+
+The RAS framework allows the platform to define handlers for External Abort,
+Uncontainable Errors, Double Fault, and errors rising from EL3 execution. Please
+refer to the porting guide for the `RAS platform API descriptions`__.
+
+.. __: ../getting_started/porting-guide.rst#external-abort-handling-and-ras-support
+
+Registering RAS error records
+-----------------------------
+
+RAS nodes are components in the system capable of signalling errors to PEs
+through one one of the notification mechanisms—SEAs, SErrors, or interrupts. RAS
+nodes contain one or more error records, which are registers through which the
+nodes advertise various properties of the signalled error. Arm recommends that
+error records are implemented in the Standard Error Record format. The RAS
+architecture allows for error records to be accessible via system or
+memory-mapped registers.
+
+The platform should enumerate the error records providing for each of them:
+
+- A handler to probe error records for errors;
+- When the probing identifies an error, a handler to handle it;
+- For memory-mapped error record, its base address and size in KB; for a system
+ register-accessed record, the start index of the record and number of
+ continuous records from that index;
+- Any node-specific auxiliary data.
+
+With this information supplied, when the run time firmware receives one of the
+notification mechanisms, the RAS framework can iterate through and probe error
+records for error, and invoke the appropriate handler to handle it.
+
+The RAS framework provides the macros to populate error record information. The
+macros are versioned, and the latest version as of this writing is 1. These
+macros create a structure of type ``struct err_record_info`` from its arguments,
+which are later passed to probe and error handlers.
+
+For memory-mapped error records:
+
+.. code:: c
+
+ ERR_RECORD_MEMMAP_V1(base_addr, size_num_k, probe, handler, aux)
+
+And, for system register ones:
+
+.. code:: c
+
+ ERR_RECORD_SYSREG_V1(idx_start, num_idx, probe, handler, aux)
+
+The probe handler must have the following prototype:
+
+.. code:: c
+
+ typedef int (*err_record_probe_t)(const struct err_record_info *info,
+ int *probe_data);
+
+The probe handler must return a non-zero value if an error was detected, or 0
+otherwise. The ``probe_data`` output parameter can be used to pass any useful
+information resulting from probe to the error handler (see `below`__). For
+example, it could return the index of the record.
+
+.. __: `Standard Error Record helpers`_
+
+The error handler must have the following prototype:
+
+.. code:: c
+
+ typedef int (*err_record_handler_t)(const struct err_record_info *info,
+ int probe_data, const struct err_handler_data *const data);
+
+The ``data`` constant parameter describes the various properties of the error,
+including the reason for the error, exception syndrome, and also ``flags``,
+``cookie``, and ``handle`` parameters from the `top-level exception handler`__.
+
+.. __: interrupt-framework-design.rst#el3-interrupts
+
+The platform is expected populate an array using the macros above, and register
+the it with the RAS framework using the macro ``REGISTER_ERR_RECORD_INFO()``,
+passing it the name of the array describing the records. Note that the macro
+must be used in the same file where the array is defined.
+
+Standard Error Record helpers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The |TF-A| RAS framework provides probe handlers for Standard Error Records, for
+both memory-mapped and System Register accesses:
+
+.. code:: c
+
+ int ras_err_ser_probe_memmap(const struct err_record_info *info,
+ int *probe_data);
+
+ int ras_err_ser_probe_sysreg(const struct err_record_info *info,
+ int *probe_data);
+
+When the platform enumerates error records, for those records in the Standard
+Error Record format, these helpers maybe used instead of rolling out their own.
+Both helpers above:
+
+- Return non-zero value when an error is detected in a Standard Error Record;
+- Set ``probe_data`` to the index of the error record upon detecting an error.
+
+Registering RAS interrupts
+--------------------------
+
+RAS nodes can signal errors to the PE by raising Fault Handling and/or Error
+Recovery interrupts. For the firmware-first handling paradigm for interrupts to
+work, the platform must setup and register with |EHF|. See `Interaction with
+Exception Handling Framework`_.
+
+For each RAS interrupt, the platform has to provide structure of type ``struct
+ras_interrupt``:
+
+- Interrupt number;
+- The associated error record information (pointer to the corresponding
+ ``struct err_record_info``);
+- Optionally, a cookie.
+
+The platform is expected to define an array of ``struct ras_interrupt``, and
+register it with the RAS framework using the macro
+``REGISTER_RAS_INTERRUPTS()``, passing it the name of the array. Note that the
+macro must be used in the same file where the array is defined.
+
+The array of ``struct ras_interrupt`` must be sorted in the increasing order of
+interrupt number. This allows for fast look of handlers in order to service RAS
+interrupts.
+
+Double-fault handling
+---------------------
+
+A Double Fault condition arises when an error is signalled to the PE while
+handling of a previously signalled error is still underway. When a Double Fault
+condition arises, the Arm RAS extensions only require for handler to perform
+orderly shutdown of the system, as recovery may be impossible.
+
+The RAS extensions part of Armv8.4 introduced new architectural features to deal
+with Double Fault conditions, specifically, the introduction of ``NMEA`` and
+``EASE`` bits to ``SCR_EL3`` register. These were introduced to assist EL3
+software which runs part of its entry/exit routines with exceptions momentarily
+masked—meaning, in such systems, External Aborts/SErrors are not immediately
+handled when they occur, but only after the exceptions are unmasked again.
+
+|TF-A|, for legacy reasons, executes entire EL3 with all exceptions unmasked.
+This means that all exceptions routed to EL3 are handled immediately. |TF-A|
+thus is able to detect a Double Fault conditions in software, without needing
+the intended advantages of Armv8.4 Double Fault architecture extensions.
+
+Double faults are fatal, and terminate at the platform double fault handler, and
+doesn't return.
+
+Engaging the RAS framework
+--------------------------
+
+Enabling RAS support is a platform choice constructed from three distinct, but
+related, build options:
+
+- ``RAS_EXTENSION=1`` includes the RAS framework in the run time firmware;
+
+- ``EL3_EXCEPTION_HANDLING=1`` enables handling of exceptions at EL3. See
+ `Interaction with Exception Handling Framework`_;
+
+- ``HANDLE_EA_EL3_FIRST=1`` enables routing of External Aborts and SErrors to
+ EL3.
+
+The RAS support in |TF-A| introduces a default implementation of
+``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_EXTENSION``
+is set to ``1``, it'll first call ``ras_ea_handler()`` function, which is the
+top-level RAS exception handler. ``ras_ea_handler`` is responsible for iterating
+to through platform-supplied error records, probe them, and when an error is
+identified, look up and invoke the corresponding error handler.
+
+Note that, if the platform chooses to override the ``plat_ea_handler`` function
+and intend to use the RAS framework, it must explicitly call
+``ras_ea_handler()`` from within.
+
+Similarly, for RAS interrupts, the framework defines
+``ras_interrupt_handler()``. The RAS framework arranges for it to be invoked
+when a RAS interrupt taken at EL3. The function bisects the platform-supplied
+sorted array of interrupts to look up the error record information associated
+with the interrupt number. That error handler for that record is then invoked to
+handle the error.
+
+Interaction with Exception Handling Framework
+---------------------------------------------
+
+As mentioned in earlier sections, RAS framework interacts with the |EHF| to
+arbitrate handling of RAS exceptions with others that are routed to EL3. This
+means that the platform must partition a `priority level`__ for handling RAS
+exceptions. The platform must then define the macro ``PLAT_RAS_PRI`` to the
+priority level used for RAS exceptions. Platforms would typically want to
+allocate the highest secure priority for RAS handling.
+
+.. __: exception-handling.rst#partitioning-priority-levels
+
+Handling of both `interrupt`__ and `non-interrupt`__ exceptions follow the
+sequences outlined in the |EHF| documentation. I.e., for interrupts, the
+priority management is implicit; but for non-interrupt exceptions, they're
+explicit using `EHF APIs`__.
+
+.. __: exception-handling.rst#interrupt-flow
+.. __: exception-handling.rst#non-interrupt-flow
+.. __: exception-handling.rst#activating-and-deactivating-priorities
+
+----
+
+*Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.*
--- /dev/null
+Library at ROM
+==============
+
+.. section-numbering::
+ :suffix: .
+
+.. contents::
+
+This document provides an overview of the "library at ROM" implementation in
+Trusted Firmware-A (TF-A).
+
+Introduction
+~~~~~~~~~~~~
+
+The "library at ROM" feature allows platforms to build a library of functions to
+be placed in ROM. This reduces SRAM usage by utilising the available space in
+ROM. The "library at ROM" contains a jump table with the list of functions that
+are placed in ROM. The capabilities of the "library at ROM" are:
+
+1. Functions can be from one or several libraries.
+
+2. Functions can be patched after they have been programmed into ROM.
+
+3. Platform-specific libraries can be placed in ROM.
+
+4. Functions can be accessed by one or more BL images.
+
+Index file
+~~~~~~~~~~
+
+.. image:: diagrams/romlib_design.png
+ :width: 600
+
+Library at ROM is described by an index file with the list of functions to be
+placed in ROM. The index file is platform specific and its format is:
+
+::
+
+ lib function [patch]
+
+ lib -- Name of the library the function belongs to
+ function -- Name of the function to be placed in library at ROM
+ [patch] -- Option to patch the function
+
+It is also possible to insert reserved spaces in the list by using the keyword
+"reserved" rather than the "lib" and "function" names as shown below:
+
+::
+
+ reserved reserved
+
+The reserved spaces can be used to add more functions in the future without
+affecting the order and location of functions already existing in the jump
+table. Also, for additional flexibility and modularity, the index file can
+include other index files.
+
+For an index file example, refer to ``lib/romlib/jmptbl.i``.
+
+Wrapper functions
+~~~~~~~~~~~~~~~~~
+
+.. image:: diagrams/romlib_wrapper.png
+ :width: 600
+
+When invoking a function of the "library at ROM", the calling sequence is as
+follows:
+
+BL image --> wrapper function --> jump table entry --> library at ROM
+
+The index file is used to create a jump table which is placed in ROM. Then, the
+wrappers refer to the jump table to call the "library at ROM" functions. The
+wrappers essentially contain a branch instruction to the jump table entry
+corresponding to the original function. Finally, the original function in the BL
+image(s) is replaced with the wrapper function.
+
+The "library at ROM" contains a necessary init function that initialises the
+global variables defined by the functions inside "library at ROM".
+
+Scripts
+~~~~~~~
+
+There are several scripts that generate the necessary files for the "library at
+ROM" to work:
+
+1. ``gentbl.sh`` - Generates the jump table by parsing the index file.
+
+2. ``genvar.sh`` - Generates the jump table global variable (**not** the jump
+ table itself) with the absolute address in ROM. This global variable is,
+ basically, a pointer to the jump table.
+
+3. ``genwrappers.sh`` - Generates a wrapper function for each entry in the index
+ file except for the ones that contain the keyword ``patch``. The generated
+ wrapper file is called ``<lib>_<fn_name>.S``.
+
+Patching of functions in library at ROM
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``genwrappers.sh`` script does not generate wrappers for the entries in the
+index file that contain the keyword ``patch``. Thus, it allows calling the
+function from the actual library by breaking the link to the "library at ROM"
+version of this function.
+
+The calling sequence for a patched function is as follows:
+
+BL image --> function
+
+Build library at ROM
+~~~~~~~~~~~~~~~~~~~~~
+
+The environment variable ``CROSS_COMPILE`` must be set as per the user guide.
+In the below example the usage of ROMLIB together with mbed TLS is demonstrated
+to showcase the benefits of library at ROM - it's not mandatory.
+
+::
+
+ make PLAT=fvp \
+ MBEDTLS_DIR=</path/to/mbedtls/> \
+ TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \
+ ARM_ROTPK_LOCATION=devel_rsa \
+ ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
+ BL33=</path/to/bl33.bin> \
+ USE_ROMLIB=1 \
+ all fip
+
+Known issue
+-----------
+When building library at ROM, a clean build is always required. This is
+necessary when changes are made to the index files, e.g. adding new functions,
+patching existing ones etc.
+
+--------------
+
+*Copyright (c) 2019, Arm Limited. All rights reserved.*
--- /dev/null
+SDEI: Software Delegated Exception Interface
+============================================
+
+.. contents::
+ :depth: 2
+
+This document provides an overview of the SDEI dispatcher implementation in
+Trusted Firmware-A (TF-A).
+
+Introduction
+------------
+
+`Software Delegated Exception Interface`_ (SDEI) is an Arm specification for
+Non-secure world to register handlers with firmware to receive notifications
+about system events. Firmware will first receive the system events by way of
+asynchronous exceptions and, in response, arranges for the registered handler to
+execute in the Non-secure EL.
+
+Normal world software that interacts with the SDEI dispatcher (makes SDEI
+requests and receives notifications) is referred to as the *SDEI Client*. A
+client receives the event notification at the registered handler even when it
+was executing with exceptions masked. The list of SDEI events available to the
+client are specific to the platform [#std-event]_. See also `Determining client
+EL`_.
+
+.. _general SDEI dispatch:
+
+The following figure depicts a general sequence involving SDEI client executing
+at EL2 and an event dispatch resulting from the triggering of a bound interrupt.
+A commentary is provided below:
+
+.. image:: ../plantuml/sdei_general.svg
+
+As part of initialisation, the SDEI client binds a Non-secure interrupt [1], and
+the SDEI dispatcher returns a platform dynamic event number [2]. The client then
+registers a handler for that event [3], enables the event [5], and unmasks all
+events on the current PE [7]. This sequence is typical of an SDEI client, but it
+may involve additional SDEI calls.
+
+At a later point in time, when the bound interrupt triggers [9], it's trapped to
+EL3. The interrupt is handed over to the SDEI dispatcher, which then arranges to
+execute the registered handler [10]. The client terminates its execution with
+``SDEI_EVENT_COMPLETE`` [11], following which the dispatcher resumes the
+original EL2 execution [13]. Note that the SDEI interrupt remains active until
+the client handler completes, at which point EL3 does EOI [12].
+
+Other than events bound to interrupts (as depicted in the sequence above, SDEI
+events can be explicitly dispatched in response to other exceptions, for
+example, upon receiving an *SError* or *Synchronous External Abort*. See
+`Explicit dispatch of events`_.
+
+The remainder of this document only discusses the design and implementation of
+SDEI dispatcher in TF-A, and assumes that the reader is familiar with the SDEI
+specification, the interfaces, and their requirements.
+
+.. [#std-event] Except event 0, which is defined by the SDEI specification as a
+ standard event.
+
+Defining events
+---------------
+
+A platform choosing to include the SDEI dispatcher must also define the events
+available on the platform, along with their attributes.
+
+The platform is expected to provide two arrays of event descriptors: one for
+private events, and another for shared events. The SDEI dispatcher provides
+``SDEI_PRIVATE_EVENT()`` and ``SDEI_SHARED_EVENT()`` macros to populate the
+event descriptors. Both macros take 3 arguments:
+
+- The event number: this must be a positive 32-bit integer.
+
+- For an event that has a backing interrupt, the interrupt number the event is
+ bound to:
+
+ - If it's not applicable to an event, this shall be left as ``0``.
+
+ - If the event is dynamic, this should be specified as ``SDEI_DYN_IRQ``.
+
+- A bit map of `Event flags`_.
+
+To define event 0, the macro ``SDEI_DEFINE_EVENT_0()`` should be used. This
+macro takes only one parameter: an SGI number to signal other PEs.
+
+To define an event that's meant to be `explicitly dispatched`__ (i.e., not as a
+result of receiving an SDEI interrupt), the macro ``SDEI_EXPLICIT_EVENT()``
+should be used. It accepts two parameters:
+
+.. __: `Explicit dispatch of events`_
+
+- The event number (as above);
+
+- Event priority: ``SDEI_MAPF_CRITICAL`` or ``SDEI_MAPF_NORMAL``, as described
+ below.
+
+Once the event descriptor arrays are defined, they should be exported to the
+SDEI dispatcher using the ``REGISTER_SDEI_MAP()`` macro, passing it the pointers
+to the private and shared event descriptor arrays, respectively. Note that the
+``REGISTER_SDEI_MAP()`` macro must be used in the same file where the arrays are
+defined.
+
+Regarding event descriptors:
+
+- For Event 0:
+
+ - There must be exactly one descriptor in the private array, and none in the
+ shared array.
+
+ - The event should be defined using ``SDEI_DEFINE_EVENT_0()``.
+
+ - Must be bound to a Secure SGI on the platform.
+
+- Explicit events should only be used in the private array.
+
+- Statically bound shared and private interrupts must be bound to shared and
+ private interrupts on the platform, respectively. See the section on
+ `interrupt configuration`__.
+
+ .. __: `Configuration within Exception Handling Framework`_
+
+- Both arrays should be one-dimensional. The ``REGISTER_SDEI_MAP()`` macro
+ takes care of replicating private events for each PE on the platform.
+
+- Both arrays must be sorted in the increasing order of event number.
+
+The SDEI specification doesn't have provisions for discovery of available events
+on the platform. The list of events made available to the client, along with
+their semantics, have to be communicated out of band; for example, through
+Device Trees or firmware configuration tables.
+
+See also `Event definition example`_.
+
+Event flags
+~~~~~~~~~~~
+
+Event flags describe the properties of the event. They are bit maps that can be
+``OR``\ ed to form parameters to macros that `define events`__.
+
+.. __: `Defining events`_
+
+- ``SDEI_MAPF_DYNAMIC``: Marks the event as dynamic. Dynamic events can be
+ bound to (or released from) any Non-secure interrupt at runtime via the
+ ``SDEI_INTERRUPT_BIND`` and ``SDEI_INTERRUPT_RELEASE`` calls.
+
+- ``SDEI_MAPF_BOUND``: Marks the event as statically bound to an interrupt.
+ These events cannot be re-bound at runtime.
+
+- ``SDEI_MAPF_NORMAL``: Marks the event as having *Normal* priority. This is
+ the default priority.
+
+- ``SDEI_MAPF_CRITICAL``: Marks the event as having *Critical* priority.
+
+Event definition example
+------------------------
+
+.. code:: c
+
+ static sdei_ev_map_t plat_private_sdei[] = {
+ /* Event 0 definition */
+ SDEI_DEFINE_EVENT_0(8),
+
+ /* PPI */
+ SDEI_PRIVATE_EVENT(8, 23, SDEI_MAPF_BOUND),
+
+ /* Dynamic private events */
+ SDEI_PRIVATE_EVENT(100, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_PRIVATE_EVENT(101, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+
+ /* Events for explicit dispatch */
+ SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_NORMAL);
+ SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_CRITICAL);
+ };
+
+ /* Shared event mappings */
+ static sdei_ev_map_t plat_shared_sdei[] = {
+ SDEI_SHARED_EVENT(804, 0, SDEI_MAPF_DYNAMIC),
+
+ /* Dynamic shared events */
+ SDEI_SHARED_EVENT(3000, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
+ SDEI_SHARED_EVENT(3001, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
+ };
+
+ /* Export SDEI events */
+ REGISTER_SDEI_MAP(plat_private_sdei, plat_shared_sdei);
+
+Configuration within Exception Handling Framework
+-------------------------------------------------
+
+The SDEI dispatcher functions alongside the Exception Handling Framework. This
+means that the platform must assign priorities to both Normal and Critical SDEI
+interrupts for the platform:
+
+- Install priority descriptors for Normal and Critical SDEI interrupts.
+
+- For those interrupts that are statically bound (i.e. events defined as having
+ the ``SDEI_MAPF_BOUND`` property), enumerate their properties for the GIC
+ driver to configure interrupts accordingly.
+
+ The interrupts must be configured to target EL3. This means that they should
+ be configured as *Group 0*. Additionally, on GICv2 systems, the build option
+ ``GICV2_G0_FOR_EL3`` must be set to ``1``.
+
+See also `SDEI porting requirements`_.
+
+Determining client EL
+---------------------
+
+The SDEI specification requires that the *physical* SDEI client executes in the
+highest Non-secure EL implemented on the system. This means that the dispatcher
+will only allow SDEI calls to be made from:
+
+- EL2, if EL2 is implemented. The Hypervisor is expected to implement a
+ *virtual* SDEI dispatcher to support SDEI clients in Guest Operating Systems
+ executing in Non-secure EL1.
+
+- Non-secure EL1, if EL2 is not implemented or disabled.
+
+See the function ``sdei_client_el()`` in ``sdei_private.h``.
+
+Explicit dispatch of events
+---------------------------
+
+Typically, an SDEI event dispatch is caused by the PE receiving interrupts that
+are bound to an SDEI event. However, there are cases where the Secure world
+requires dispatch of an SDEI event as a direct or indirect result of a past
+activity, such as receiving a Secure interrupt or an exception.
+
+The SDEI dispatcher implementation provides ``sdei_dispatch_event()`` API for
+this purpose. The API has the following signature:
+
+::
+
+ int sdei_dispatch_event(int ev_num);
+
+The parameter ``ev_num`` is the event number to dispatch. The API returns ``0``
+on success, or ``-1`` on failure.
+
+The following figure depicts a scenario involving explicit dispatch of SDEI
+event. A commentary is provided below:
+
+.. image:: ../plantuml/sdei_explicit_dispatch.svg
+
+As part of initialisation, the SDEI client registers a handler for a platform
+event [1], enables the event [3], and unmasks the current PE [5]. Note that,
+unlike in `general SDEI dispatch`_, this doesn't involve interrupt binding, as
+bound or dynamic events can't be explicitly dispatched (see the section below).
+
+At a later point in time, a critical event [#critical-event]_ is trapped into
+EL3 [7]. EL3 performs a first-level triage of the event, and a RAS component
+assumes further handling [8]. The dispatch completes, but intends to involve
+Non-secure world in further handling, and therefore decides to explicitly
+dispatch an event [10] (which the client had already registered for [1]). The
+rest of the sequence is similar to that in the `general SDEI dispatch`_: the
+requested event is dispatched to the client (assuming all the conditions are
+met), and when the handler completes, the preempted execution resumes.
+
+.. [#critical-event] Examples of critical event are *SError*, *Synchronous
+ External Abort*, *Fault Handling interrupt*, or *Error
+ Recovery interrupt* from one of RAS nodes in the system.
+
+Conditions for event dispatch
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+All of the following requirements must be met for the API to return ``0`` and
+event to be dispatched:
+
+- SDEI events must be unmasked on the PE. I.e. the client must have called
+ ``PE_UNMASK`` beforehand.
+
+- Event 0 can't be dispatched.
+
+- The event must be declared using the ``SDEI_EXPLICIT_EVENT()`` macro
+ described above.
+
+- The event must be private to the PE.
+
+- The event must have been registered for and enabled.
+
+- A dispatch for the same event must not be outstanding. I.e. it hasn't already
+ been dispatched and is yet to be completed.
+
+- The priority of the event (either Critical or Normal, as configured by the
+ platform at build-time) shouldn't cause priority inversion. This means:
+
+ - If it's of Normal priority, neither Normal nor Critical priority dispatch
+ must be outstanding on the PE.
+
+ - If it's of a Critical priority, no Critical priority dispatch must be
+ outstanding on the PE.
+
+Further, the caller should be aware of the following assumptions made by the
+dispatcher:
+
+- The caller of the API is a component running in EL3; for example, a RAS
+ driver.
+
+- The requested dispatch will be permitted by the Exception Handling Framework.
+ I.e. the caller must make sure that the requested dispatch has sufficient
+ priority so as not to cause priority level inversion within Exception
+ Handling Framework.
+
+- The caller must be prepared for the SDEI dispatcher to restore the Non-secure
+ context, and mark that the active context.
+
+- The call will block until the SDEI client completes the event (i.e. when the
+ client calls either ``SDEI_EVENT_COMPLETE`` or ``SDEI_COMPLETE_AND_RESUME``).
+
+- The caller must be prepared for this API to return failure and handle
+ accordingly.
+
+Porting requirements
+--------------------
+
+The porting requirements of the SDEI dispatcher are outlined in the `porting
+guide`__.
+
+.. __: `SDEI porting requirements`_
+
+Note on writing SDEI event handlers
+-----------------------------------
+
+*This section pertains to SDEI event handlers in general, not just when using
+the TF-A SDEI dispatcher.*
+
+The SDEI specification requires that event handlers preserve the contents of all
+registers except ``x0`` to ``x17``. This has significance if event handler is
+written in C: compilers typically adjust the stack frame at the beginning and
+end of C functions. For example, AArch64 GCC typically produces the following
+function prologue and epilogue:
+
+::
+
+ c_event_handler:
+ stp x29, x30, [sp,#-32]!
+ mov x29, sp
+
+ ...
+
+ bl ...
+
+ ...
+
+ ldp x29, x30, [sp],#32
+ ret
+
+The register ``x29`` is used as frame pointer in the prologue. Because neither a
+valid ``SDEI_EVENT_COMPLETE`` nor ``SDEI_EVENT_COMPLETE_AND_RESUME`` calls
+return to the handler, the epilogue never gets executed, and registers ``x29``
+and ``x30`` (in the case above) are inadvertently corrupted. This violates the
+SDEI specification, and the normal execution thereafter will result in
+unexpected behaviour.
+
+To work this around, it's advised that the top-level event handlers are
+implemented in assembly, following a similar pattern as below:
+
+::
+
+ asm_event_handler:
+ /* Save link register whilst maintaining stack alignment */
+ stp xzr, x30, [sp, #-16]!
+ bl c_event_handler
+
+ /* Restore link register */
+ ldp xzr, x30, [sp], #16
+
+ /* Complete call */
+ ldr x0, =SDEI_EVENT_COMPLETE
+ smc #0
+ b .
+
+----
+
+*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
+.. _SDEI porting requirements: ../getting_started/porting-guide.rst#sdei-porting-requirements
--- /dev/null
+*******************************
+Secure Partition Manager Design
+*******************************
+
+
+
+.. contents::
+
+Background
+==========
+
+In some market segments that primarily deal with client-side devices like mobile
+phones, tablets, STBs and embedded devices, a Trusted OS instantiates trusted
+applications to provide security services like DRM, secure payment and
+authentication. The Global Platform TEE Client API specification defines the API
+used by Non-secure world applications to access these services. A Trusted OS
+fulfils the requirements of a security service as described above.
+
+Management services are typically implemented at the highest level of privilege
+in the system, i.e. EL3 in Trusted Firmware-A (TF-A). The service requirements are
+fulfilled by the execution environment provided by TF-A.
+
+The following diagram illustrates the corresponding software stack:
+
+|Image 1|
+
+In other market segments that primarily deal with server-side devices (e.g. data
+centres and enterprise servers) the secure software stack typically does not
+include a Global Platform Trusted OS. Security functions are accessed through
+other interfaces (e.g. ACPI TCG TPM interface, UEFI runtime variable service).
+
+Placement of management and security functions with diverse requirements in a
+privileged Exception Level (i.e. EL3 or S-EL1) makes security auditing of
+firmware more difficult and does not allow isolation of unrelated services from
+each other either.
+
+Introduction
+============
+
+A **Secure Partition** is a software execution environment instantiated in
+S-EL0 that can be used to implement simple management and security services.
+Since S-EL0 is an unprivileged Exception Level, a Secure Partition relies on
+privileged firmware (i.e. TF-A) to be granted access to system and processor
+resources. Essentially, it is a software sandbox in the Secure world that runs
+under the control of privileged software, provides one or more services and
+accesses the following system resources:
+
+- Memory and device regions in the system address map.
+
+- PE system registers.
+
+- A range of synchronous exceptions (e.g. SMC function identifiers).
+
+Note that currently TF-A only supports handling one Secure Partition.
+
+A Secure Partition enables TF-A to implement only the essential secure
+services in EL3 and instantiate the rest in a partition in S-EL0.
+Furthermore, multiple Secure Partitions can be used to isolate unrelated
+services from each other.
+
+The following diagram illustrates the place of a Secure Partition in a typical
+Armv8-A software stack. A single or multiple Secure Partitions provide secure
+services to software components in the Non-secure world and other Secure
+Partitions.
+
+|Image 2|
+
+The TF-A build system is responsible for including the Secure Partition image
+in the FIP. During boot, BL2 includes support to authenticate and load the
+Secure Partition image. A BL31 component called **Secure Partition Manager
+(SPM)** is responsible for managing the partition. This is semantically
+similar to a hypervisor managing a virtual machine.
+
+The SPM is responsible for the following actions during boot:
+
+- Allocate resources requested by the Secure Partition.
+
+- Perform architectural and system setup required by the Secure Partition to
+ fulfil a service request.
+
+- Implement a standard interface that is used for initialising a Secure
+ Partition.
+
+The SPM is responsible for the following actions during runtime:
+
+- Implement a standard interface that is used by a Secure Partition to fulfil
+ service requests.
+
+- Implement a standard interface that is used by the Non-secure world for
+ accessing the services exported by a Secure Partition. A service can be
+ invoked through a SMC.
+
+Alternatively, a partition can be viewed as a thread of execution running under
+the control of the SPM. Hence common programming concepts described below are
+applicable to a partition.
+
+Description
+===========
+
+The previous section introduced some general aspects of the software
+architecture of a Secure Partition. This section describes the specific choices
+made in the current implementation of this software architecture. Subsequent
+revisions of the implementation will include a richer set of features that
+enable a more flexible architecture.
+
+Building TF-A with Secure Partition support
+-------------------------------------------
+
+SPM is supported on the Arm FVP exclusively at the moment. The current
+implementation supports inclusion of only a single Secure Partition in which a
+service always runs to completion (e.g. the requested services cannot be
+preempted to give control back to the Normal world).
+
+It is not currently possible for BL31 to integrate SPM support and a Secure
+Payload Dispatcher (SPD) at the same time; they are mutually exclusive. In the
+SPM bootflow, a Secure Partition image executing at S-EL0 replaces the Secure
+Payload image executing at S-EL1 (e.g. a Trusted OS). Both are referred to as
+BL32.
+
+A working prototype of a SP has been implemented by re-purposing the EDK2 code
+and tools, leveraging the concept of the *Standalone Management Mode (MM)* in
+the UEFI specification (see the PI v1.6 Volume 4: Management Mode Core
+Interface). This will be referred to as the *Standalone MM Secure Partition* in
+the rest of this document.
+
+To enable SPM support in TF-A, the source code must be compiled with the build
+flag ``ENABLE_SPM=1``, along with ``EL3_EXCEPTION_HANDLING=1``. On Arm
+platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the
+location of the binary that contains the BL32 image
+(``BL32=path/to/image.bin``) must be specified.
+
+First, build the Standalone MM Secure Partition. To build it, refer to the
+`instructions in the EDK2 repository`_.
+
+Then build TF-A with SPM support and include the Standalone MM Secure Partition
+image in the FIP:
+
+::
+
+ BL32=path/to/standalone/mm/sp BL33=path/to/bl33.bin \
+ make PLAT=fvp ENABLE_SPM=1 ARM_BL31_IN_DRAM=1 fip all
+
+Describing Secure Partition resources
+-------------------------------------
+
+TF-A exports a porting interface that enables a platform to specify the system
+resources required by the Secure Partition. Some instructions are given below.
+However, this interface is under development and it may change as new features
+are implemented.
+
+- A Secure Partition is considered a BL32 image, so the same defines that apply
+ to BL32 images apply to a Secure Partition: ``BL32_BASE`` and ``BL32_LIMIT``.
+
+- The following defines are needed to allocate space for the translation tables
+ used by the Secure Partition: ``PLAT_SP_IMAGE_MMAP_REGIONS`` and
+ ``PLAT_SP_IMAGE_MAX_XLAT_TABLES``.
+
+- The functions ``plat_get_secure_partition_mmap()`` and
+ ``plat_get_secure_partition_boot_info()`` have to be implemented. The file
+ ``plat/arm/board/fvp/fvp_common.c`` can be used as an example. It uses the
+ defines in ``include/plat/arm/common/arm_spm_def.h``.
+
+ - ``plat_get_secure_partition_mmap()`` returns an array of mmap regions that
+ describe the memory regions that the SPM needs to allocate for a Secure
+ Partition.
+
+ - ``plat_get_secure_partition_boot_info()`` returns a
+ ``secure_partition_boot_info_t`` struct that is populated by the platform
+ with information about the memory map of the Secure Partition.
+
+For an example of all the changes in context, you may refer to commit
+``e29efeb1b4``, in which the port for FVP was introduced.
+
+Accessing Secure Partition services
+-----------------------------------
+
+The `SMC Calling Convention`_ (*Arm DEN 0028B*) describes SMCs as a conduit for
+accessing services implemented in the Secure world. The ``MM_COMMUNICATE``
+interface defined in the `Management Mode Interface Specification`_ (*Arm DEN
+0060A*) is used to invoke a Secure Partition service as a Fast Call.
+
+The mechanism used to identify a service within the partition depends on the
+service implementation. It is assumed that the caller of the service will be
+able to discover this mechanism through standard platform discovery mechanisms
+like ACPI and Device Trees. For example, *Volume 4: Platform Initialisation
+Specification v1.6. Management Mode Core Interface* specifies that a GUID is
+used to identify a management mode service. A client populates the GUID in the
+``EFI_MM_COMMUNICATE_HEADER``. The header is populated in the communication
+buffer shared with the Secure Partition.
+
+A Fast Call appears to be atomic from the perspective of the caller and returns
+when the requested operation has completed. A service invoked through the
+``MM_COMMUNICATE`` SMC will run to completion in the partition on a given CPU.
+The SPM is responsible for guaranteeing this behaviour. This means that there
+can only be a single outstanding Fast Call in a partition on a given CPU.
+
+Exchanging data with the Secure Partition
+-----------------------------------------
+
+The exchange of data between the Non-secure world and the partition takes place
+through a shared memory region. The location of data in the shared memory area
+is passed as a parameter to the ``MM_COMMUNICATE`` SMC. The shared memory area
+is statically allocated by the SPM and is expected to be either implicitly known
+to the Non-secure world or discovered through a platform discovery mechanism
+e.g. ACPI table or device tree. It is possible for the Non-secure world to
+exchange data with a partition only if it has been populated in this shared
+memory area. The shared memory area is implemented as per the guidelines
+specified in Section 3.2.3 of the `Management Mode Interface Specification`_
+(*Arm DEN 0060A*).
+
+The format of data structures used to encapsulate data in the shared memory is
+agreed between the Non-secure world and the Secure Partition. For example, in
+the `Management Mode Interface specification`_ (*Arm DEN 0060A*), Section 4
+describes that the communication buffer shared between the Non-secure world and
+the Management Mode (MM) in the Secure world must be of the type
+``EFI_MM_COMMUNICATE_HEADER``. This data structure is defined in *Volume 4:
+Platform Initialisation Specification v1.6. Management Mode Core Interface*.
+Any caller of a MM service will have to use the ``EFI_MM_COMMUNICATE_HEADER``
+data structure.
+
+Runtime model of the Secure Partition
+=====================================
+
+This section describes how the Secure Partition interfaces with the SPM.
+
+Interface with SPM
+------------------
+
+In order to instantiate one or more secure services in the Secure Partition in
+S-EL0, the SPM should define the following types of interfaces:
+
+- Interfaces that enable access to privileged operations from S-EL0. These
+ operations typically require access to system resources that are either shared
+ amongst multiple software components in the Secure world or cannot be directly
+ accessed from an unprivileged Exception Level.
+
+- Interfaces that establish the control path between the SPM and the Secure
+ Partition.
+
+This section describes the APIs currently exported by the SPM that enable a
+Secure Partition to initialise itself and export its services in S-EL0. These
+interfaces are not accessible from the Non-secure world.
+
+Conduit
+^^^^^^^
+
+The `SMC Calling Convention`_ (*Arm DEN 0028B*) specification describes the SMC
+and HVC conduits for accessing firmware services and their availability
+depending on the implemented Exception levels. In S-EL0, the Supervisor Call
+exception (SVC) is the only architectural mechanism available for unprivileged
+software to make a request for an operation implemented in privileged software.
+Hence, the SVC conduit must be used by the Secure Partition to access interfaces
+implemented by the SPM.
+
+A SVC causes an exception to be taken to S-EL1. TF-A assumes ownership of S-EL1
+and installs a simple exception vector table in S-EL1 that relays a SVC request
+from a Secure Partition as a SMC request to the SPM in EL3. Upon servicing the
+SMC request, Arm Trusted Firmware returns control directly to S-EL0 through an
+ERET instruction.
+
+Calling conventions
+^^^^^^^^^^^^^^^^^^^
+
+The `SMC Calling Convention`_ (*Arm DEN 0028B*) specification describes the
+32-bit and 64-bit calling conventions for the SMC and HVC conduits. The SVC
+conduit introduces the concept of SVC32 and SVC64 calling conventions. The SVC32
+and SVC64 calling conventions are equivalent to the 32-bit (SMC32) and the
+64-bit (SMC64) calling conventions respectively.
+
+Communication initiated by SPM
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A service request is initiated from the SPM through an exception return
+instruction (ERET) to S-EL0. Later, the Secure Partition issues an SVC
+instruction to signal completion of the request. Some example use cases are
+given below:
+
+- A request to initialise the Secure Partition during system boot.
+
+- A request to handle a runtime service request.
+
+Communication initiated by Secure Partition
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+A request is initiated from the Secure Partition by executing a SVC instruction.
+An ERET instruction is used by TF-A to return to S-EL0 with the result of the
+request.
+
+For instance, a request to perform privileged operations on behalf of a
+partition (e.g. management of memory attributes in the translation tables for
+the Secure EL1&0 translation regime).
+
+Interfaces
+^^^^^^^^^^
+
+The current implementation reserves function IDs for Fast Calls in the Standard
+Secure Service calls range (see `SMC Calling Convention`_ (*Arm DEN 0028B*)
+specification) for each API exported by the SPM. This section defines the
+function prototypes for each function ID. The function IDs specify whether one
+or both of the SVC32 and SVC64 calling conventions can be used to invoke the
+corresponding interface.
+
+Secure Partition Event Management
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Secure Partition provides an Event Management interface that is used by the
+SPM to delegate service requests to the Secure Partition. The interface also
+allows the Secure Partition to:
+
+- Register with the SPM a service that it provides.
+- Indicate completion of a service request delegated by the SPM
+
+Miscellaneous interfaces
+------------------------
+
+``SPM_VERSION_AARCH32``
+^^^^^^^^^^^^^^^^^^^^^^^
+
+- Description
+
+ Returns the version of the interface exported by SPM.
+
+- Parameters
+
+ - **uint32** - Function ID
+
+ - SVC32 Version: **0x84000060**
+
+- Return parameters
+
+ - **int32** - Status
+
+ On success, the format of the value is as follows:
+
+ - Bit [31]: Must be 0
+ - Bits [30:16]: Major Version. Must be 0 for this revision of the SPM
+ interface.
+ - Bits [15:0]: Minor Version. Must be 1 for this revision of the SPM
+ interface.
+
+ On error, the format of the value is as follows:
+
+ - ``NOT_SUPPORTED``: SPM interface is not supported or not available for the
+ client.
+
+- Usage
+
+ This function returns the version of the Secure Partition Manager
+ implementation. The major version is 0 and the minor version is 1. The version
+ number is a 31-bit unsigned integer, with the upper 15 bits denoting the major
+ revision, and the lower 16 bits denoting the minor revision. The following
+ rules apply to the version numbering:
+
+ - Different major revision values indicate possibly incompatible functions.
+
+ - For two revisions, A and B, for which the major revision values are
+ identical, if the minor revision value of revision B is greater than the
+ minor revision value of revision A, then every function in revision A must
+ work in a compatible way with revision B. However, it is possible for
+ revision B to have a higher function count than revision A.
+
+- Implementation responsibilities
+
+ If this function returns a valid version number, all the functions that are
+ described subsequently must be implemented, unless it is explicitly stated
+ that a function is optional.
+
+See `Error Codes`_ for integer values that are associated with each return
+code.
+
+Secure Partition Initialisation
+-------------------------------
+
+The SPM is responsible for initialising the architectural execution context to
+enable initialisation of a service in S-EL0. The responsibilities of the SPM are
+listed below. At the end of initialisation, the partition issues a
+``SP_EVENT_COMPLETE_AARCH64`` call (described later) to signal readiness for
+handling requests for services implemented by the Secure Partition. The
+initialisation event is executed as a Fast Call.
+
+Entry point invocation
+^^^^^^^^^^^^^^^^^^^^^^
+
+The entry point for service requests that should be handled as Fast Calls is
+used as the target of the ERET instruction to start initialisation of the Secure
+Partition.
+
+Architectural Setup
+^^^^^^^^^^^^^^^^^^^
+
+At cold boot, system registers accessible from S-EL0 will be in their reset
+state unless otherwise specified. The SPM will perform the following
+architectural setup to enable execution in S-EL0
+
+MMU setup
+^^^^^^^^^
+
+The platform port of a Secure Partition specifies to the SPM a list of regions
+that it needs access to and their attributes. The SPM validates this resource
+description and initialises the Secure EL1&0 translation regime as follows.
+
+1. Device regions are mapped with nGnRE attributes and Execute Never
+ instruction access permissions.
+
+2. Code memory regions are mapped with RO data and Executable instruction access
+ permissions.
+
+3. Read Only data memory regions are mapped with RO data and Execute Never
+ instruction access permissions.
+
+4. Read Write data memory regions are mapped with RW data and Execute Never
+ instruction access permissions.
+
+5. If the resource description does not explicitly describe the type of memory
+ regions then all memory regions will be marked with Code memory region
+ attributes.
+
+6. The ``UXN`` and ``PXN`` bits are set for regions that are not executable by
+ S-EL0 or S-EL1.
+
+System Register Setup
+^^^^^^^^^^^^^^^^^^^^^
+
+System registers that influence software execution in S-EL0 are setup by the SPM
+as follows:
+
+1. ``SCTLR_EL1``
+
+ - ``UCI=1``
+ - ``EOE=0``
+ - ``WXN=1``
+ - ``nTWE=1``
+ - ``nTWI=1``
+ - ``UCT=1``
+ - ``DZE=1``
+ - ``I=1``
+ - ``UMA=0``
+ - ``SA0=1``
+ - ``C=1``
+ - ``A=1``
+ - ``M=1``
+
+2. ``CPACR_EL1``
+
+ - ``FPEN=b'11``
+
+3. ``PSTATE``
+
+ - ``D,A,I,F=1``
+ - ``CurrentEL=0`` (EL0)
+ - ``SpSel=0`` (Thread mode)
+ - ``NRW=0`` (AArch64)
+
+General Purpose Register Setup
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+SPM will invoke the entry point of a service by executing an ERET instruction.
+This transition into S-EL0 is special since it is not in response to a previous
+request through a SVC instruction. This is the first entry into S-EL0. The
+general purpose register usage at the time of entry will be as specified in the
+"Return State" column of Table 3-1 in Section 3.1 "Register use in AArch64 SMC
+calls" of the `SMC Calling Convention`_ (*Arm DEN 0028B*) specification. In
+addition, certain other restrictions will be applied as described below.
+
+1. ``SP_EL0``
+
+ A non-zero value will indicate that the SPM has initialised the stack pointer
+ for the current CPU.
+
+ The value will be 0 otherwise.
+
+2. ``X4-X30``
+
+ The values of these registers will be 0.
+
+3. ``X0-X3``
+
+ Parameters passed by the SPM.
+
+ - ``X0``: Virtual address of a buffer shared between EL3 and S-EL0. The
+ buffer will be mapped in the Secure EL1&0 translation regime with read-only
+ memory attributes described earlier.
+
+ - ``X1``: Size of the buffer in bytes.
+
+ - ``X2``: Cookie value (*IMPLEMENTATION DEFINED*).
+
+ - ``X3``: Cookie value (*IMPLEMENTATION DEFINED*).
+
+Runtime Event Delegation
+------------------------
+
+The SPM receives requests for Secure Partition services through a synchronous
+invocation (i.e. a SMC from the Non-secure world). These requests are delegated
+to the partition by programming a return from the last
+``SP_EVENT_COMPLETE_AARCH64`` call received from the partition. The last call
+was made to signal either completion of Secure Partition initialisation or
+completion of a partition service request.
+
+``SP_EVENT_COMPLETE_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Description
+
+ Signal completion of the last SP service request.
+
+- Parameters
+
+ - **uint32** - Function ID
+
+ - SVC64 Version: **0xC4000061**
+
+ - **int32** - Event Status Code
+
+ Zero or a positive value indicates that the event was handled successfully.
+ The values depend upon the original event that was delegated to the Secure
+ partition. They are described as follows.
+
+ - ``SUCCESS`` : Used to indicate that the Secure Partition was initialised
+ or a runtime request was handled successfully.
+
+ - Any other value greater than 0 is used to pass a specific Event Status
+ code in response to a runtime event.
+
+ A negative value indicates an error. The values of Event Status code depend
+ on the original event.
+
+- Return parameters
+
+ - **int32** - Event ID/Return Code
+
+ Zero or a positive value specifies the unique ID of the event being
+ delegated to the partition by the SPM.
+
+ In the current implementation, this parameter contains the function ID of
+ the ``MM_COMMUNICATE`` SMC. This value indicates to the partition that an
+ event has been delegated to it in response to an ``MM_COMMUNICATE`` request
+ from the Non-secure world.
+
+ A negative value indicates an error. The format of the value is as follows:
+
+ - ``NOT_SUPPORTED``: Function was called from the Non-secure world.
+
+ See `Error Codes`_ for integer values that are associated with each return
+ code.
+
+ - **uint32** - Event Context Address
+
+ Address of a buffer shared between the SPM and Secure Partition to pass
+ event specific information. The format of the data populated in the buffer
+ is implementation defined.
+
+ The buffer is mapped in the Secure EL1&0 translation regime with read-only
+ memory attributes described earlier.
+
+ For the SVC64 version, this parameter is a 64-bit Virtual Address (VA).
+
+ For the SVC32 version, this parameter is a 32-bit Virtual Address (VA).
+
+ - **uint32** - Event context size
+
+ Size of the memory starting at Event Address.
+
+ - **uint32/uint64** - Event Cookie
+
+ This is an optional parameter. If unused its value is SBZ.
+
+- Usage
+
+ This function signals to the SPM that the handling of the last event delegated
+ to a partition has completed. The partition is ready to handle its next event.
+ A return from this function is in response to the next event that will be
+ delegated to the partition. The return parameters describe the next event.
+
+- Caller responsibilities
+
+ A Secure Partition must only call ``SP_EVENT_COMPLETE_AARCH64`` to signal
+ completion of a request that was delegated to it by the SPM.
+
+- Callee responsibilities
+
+ When the SPM receives this call from a Secure Partition, the corresponding
+ syndrome information can be used to return control through an ERET
+ instruction, to the instruction immediately after the call in the Secure
+ Partition context. This syndrome information comprises of general purpose and
+ system register values when the call was made.
+
+ The SPM must save this syndrome information and use it to delegate the next
+ event to the Secure Partition. The return parameters of this interface must
+ specify the properties of the event and be populated in ``X0-X3/W0-W3``
+ registers.
+
+Secure Partition Memory Management
+----------------------------------
+
+A Secure Partition executes at S-EL0, which is an unprivileged Exception Level.
+The SPM is responsible for enabling access to regions of memory in the system
+address map from a Secure Partition. This is done by mapping these regions in
+the Secure EL1&0 Translation regime with appropriate memory attributes.
+Attributes refer to memory type, permission, cacheability and shareability
+attributes used in the Translation tables. The definitions of these attributes
+and their usage can be found in the `Armv8-A ARM`_ (*Arm DDI 0487*).
+
+All memory required by the Secure Partition is allocated upfront in the SPM,
+even before handing over to the Secure Partition for the first time. The initial
+access permissions of the memory regions are statically provided by the platform
+port and should allow the Secure Partition to run its initialisation code.
+
+However, they might not suit the final needs of the Secure Partition because its
+final memory layout might not be known until the Secure Partition initialises
+itself. As the Secure Partition initialises its runtime environment it might,
+for example, load dynamically some modules. For instance, a Secure Partition
+could implement a loader for a standard executable file format (e.g. an PE-COFF
+loader for loading executable files at runtime). These executable files will be
+a part of the Secure Partition image. The location of various sections in an
+executable file and their permission attributes (e.g. read-write data, read-only
+data and code) will be known only when the file is loaded into memory.
+
+In this case, the Secure Partition needs a way to change the access permissions
+of its memory regions. The SPM provides this feature through the
+``SP_MEMORY_ATTRIBUTES_SET_AARCH64`` SVC interface. This interface is available
+to the Secure Partition during a specific time window: from the first entry into
+the Secure Partition up to the first ``SP_EVENT_COMPLETE`` call that signals the
+Secure Partition has finished its initialisation. Once the initialisation is
+complete, the SPM does not allow changes to the memory attributes.
+
+This section describes the standard SVC interface that is implemented by the SPM
+to determine and change permission attributes of memory regions that belong to a
+Secure Partition.
+
+``SP_MEMORY_ATTRIBUTES_GET_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Description
+
+ Request the permission attributes of a memory region from S-EL0.
+
+- Parameters
+
+ - **uint32** Function ID
+
+ - SVC64 Version: **0xC4000064**
+
+ - **uint64** Base Address
+
+ This parameter is a 64-bit Virtual Address (VA).
+
+ There are no alignment restrictions on the Base Address. The permission
+ attributes of the translation granule it lies in are returned.
+
+- Return parameters
+
+ - **int32** - Memory Attributes/Return Code
+
+ On success the format of the Return Code is as follows:
+
+ - Bits[1:0] : Data access permission
+
+ - b'00 : No access
+ - b'01 : Read-Write access
+ - b'10 : Reserved
+ - b'11 : Read-only access
+
+ - Bit[2]: Instruction access permission
+
+ - b'0 : Executable
+ - b'1 : Non-executable
+
+ - Bit[30:3] : Reserved. SBZ.
+
+ - Bit[31] : Must be 0
+
+ On failure the following error codes are returned:
+
+ - ``INVALID_PARAMETERS``: The Secure Partition is not allowed to access the
+ memory region the Base Address lies in.
+
+ - ``NOT_SUPPORTED`` : The SPM does not support retrieval of attributes of
+ any memory page that is accessible by the Secure Partition, or the
+ function was called from the Non-secure world. Also returned if it is
+ used after ``SP_EVENT_COMPLETE_AARCH64``.
+
+ See `Error Codes`_ for integer values that are associated with each return
+ code.
+
+- Usage
+
+ This function is used to request the permission attributes for S-EL0 on a
+ memory region accessible from a Secure Partition. The size of the memory
+ region is equal to the Translation Granule size used in the Secure EL1&0
+ translation regime. Requests to retrieve other memory region attributes are
+ not currently supported.
+
+- Caller responsibilities
+
+ The caller must obtain the Translation Granule Size of the Secure EL1&0
+ translation regime from the SPM through an implementation defined method.
+
+- Callee responsibilities
+
+ The SPM must not return the memory access controls for a page of memory that
+ is not accessible from a Secure Partition.
+
+``SP_MEMORY_ATTRIBUTES_SET_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Description
+
+ Set the permission attributes of a memory region from S-EL0.
+
+- Parameters
+
+ - **uint32** - Function ID
+
+ - SVC64 Version: **0xC4000065**
+
+ - **uint64** - Base Address
+
+ This parameter is a 64-bit Virtual Address (VA).
+
+ The alignment of the Base Address must be greater than or equal to the size
+ of the Translation Granule Size used in the Secure EL1&0 translation
+ regime.
+
+ - **uint32** - Page count
+
+ Number of pages starting from the Base Address whose memory attributes
+ should be changed. The page size is equal to the Translation Granule Size.
+
+ - **uint32** - Memory Access Controls
+
+ - Bits[1:0] : Data access permission
+
+ - b'00 : No access
+ - b'01 : Read-Write access
+ - b'10 : Reserved
+ - b'11 : Read-only access
+
+ - Bit[2] : Instruction access permission
+
+ - b'0 : Executable
+ - b'1 : Non-executable
+
+ - Bits[31:3] : Reserved. SBZ.
+
+ A combination of attributes that mark the region with RW and Executable
+ permissions is prohibited. A request to mark a device memory region with
+ Executable permissions is prohibited.
+
+- Return parameters
+
+ - **int32** - Return Code
+
+ - ``SUCCESS``: The Memory Access Controls were changed successfully.
+
+ - ``DENIED``: The SPM is servicing a request to change the attributes of a
+ memory region that overlaps with the region specified in this request.
+
+ - ``INVALID_PARAMETER``: An invalid combination of Memory Access Controls
+ has been specified. The Base Address is not correctly aligned. The Secure
+ Partition is not allowed to access part or all of the memory region
+ specified in the call.
+
+ - ``NO_MEMORY``: The SPM does not have memory resources to change the
+ attributes of the memory region in the translation tables.
+
+ - ``NOT_SUPPORTED``: The SPM does not permit change of attributes of any
+ memory region that is accessible by the Secure Partition. Function was
+ called from the Non-secure world. Also returned if it is used after
+ ``SP_EVENT_COMPLETE_AARCH64``.
+
+ See `Error Codes`_ for integer values that are associated with each return
+ code.
+
+- Usage
+
+ This function is used to change the permission attributes for S-EL0 on a
+ memory region accessible from a Secure Partition. The size of the memory
+ region is equal to the Translation Granule size used in the Secure EL1&0
+ translation regime. Requests to change other memory region attributes are not
+ currently supported.
+
+ This function is only available at boot time. This interface is revoked after
+ the Secure Partition sends the first ``SP_EVENT_COMPLETE_AARCH64`` to signal
+ that it is initialised and ready to receive run-time requests.
+
+- Caller responsibilities
+
+ The caller must obtain the Translation Granule Size of the Secure EL1&0
+ translation regime from the SPM through an implementation defined method.
+
+- Callee responsibilities
+
+ The SPM must preserve the original memory access controls of the region of
+ memory in case of an unsuccessful call. The SPM must preserve the consistency
+ of the S-EL1 translation regime if this function is called on different PEs
+ concurrently and the memory regions specified overlap.
+
+Error Codes
+-----------
+
+.. csv-table::
+ :header: "Name", "Value"
+
+ ``SUCCESS``,0
+ ``NOT_SUPPORTED``,-1
+ ``INVALID_PARAMETER``,-2
+ ``DENIED``,-3
+ ``NO_MEMORY``,-5
+ ``NOT_PRESENT``,-7
+
+--------------
+
+*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _Armv8-A ARM: https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile
+.. _instructions in the EDK2 repository: https://github.com/tianocore/edk2-staging/blob/AArch64StandaloneMm/HowtoBuild.MD
+.. _Management Mode Interface Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0060a/DEN0060A_ARM_MM_Interface_Specification.pdf
+.. _SDEI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
+.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
+
+.. |Image 1| image:: ../diagrams/secure_sw_stack_tos.png
+.. |Image 2| image:: ../diagrams/secure_sw_stack_sp.png
--- /dev/null
+Secure Payload Dispatcher (SPD)
+===============================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+ :numbered:
+
+ optee-dispatcher
+ tlk-dispatcher
+ trusty-dispatcher
--- /dev/null
+OP-TEE Dispatcher
+=================
+
+`OP-TEE OS`_ is a Trusted OS running as Secure EL1.
+
+To build and execute OP-TEE follow the instructions at
+`OP-TEE build.git`_
+
+--------------
+
+*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _OP-TEE OS: https://github.com/OP-TEE/build
+.. _OP-TEE build.git: https://github.com/OP-TEE/build
--- /dev/null
+Trusted Little Kernel (TLK) Dispatcher
+======================================
+
+TLK dispatcher (TLK-D) adds support for NVIDIA's Trusted Little Kernel (TLK)
+to work with Trusted Firmware-A (TF-A). TLK-D can be compiled by including it
+in the platform's makefile. TLK is primarily meant to work with Tegra SoCs,
+so while TF-A only supports TLK on Tegra, the dispatcher code can only be
+compiled for other platforms.
+
+In order to compile TLK-D, we need a BL32 image to be present. Since, TLKD
+just needs to compile, any BL32 image would do. To use TLK as the BL32, please
+refer to the "Build TLK" section.
+
+Once a BL32 is ready, TLKD can be included in the image by adding "SPD=tlkd"
+to the build command.
+
+Trusted Little Kernel (TLK)
+===========================
+
+TLK is a Trusted OS running as Secure EL1. It is a Free Open Source Software
+(FOSS) release of the NVIDIA® Trusted Little Kernel (TLK) technology, which
+extends technology made available with the development of the Little Kernel (LK).
+You can download the LK modular embedded preemptive kernel for use on Arm,
+x86, and AVR32 systems from https://github.com/travisg/lk
+
+NVIDIA implemented its Trusted Little Kernel (TLK) technology, designed as a
+free and open-source trusted execution environment (OTE).
+
+TLK features include:
+
+• Small, pre-emptive kernel
+• Supports multi-threading, IPCs, and thread scheduling
+• Added TrustZone features
+• Added Secure Storage
+• Under MIT/FreeBSD license
+
+NVIDIA extensions to Little Kernel (LK) include:
+
+• User mode
+• Address-space separation for TAs
+• TLK Client Application (CA) library
+• TLK TA library
+• Crypto library (encrypt/decrypt, key handling) via OpenSSL
+• Linux kernel driver
+• Cortex A9/A15 support
+• Power Management
+• TrustZone memory carve-out (reconfigurable)
+• Page table management
+• Debugging support over UART (USB planned)
+
+TLK is hosted by NVIDIA on http://nv-tegra.nvidia.com under the
+3rdparty/ote\_partner/tlk.git repository. Detailed information about
+TLK and OTE can be found in the Tegra\_BSP\_for\_Android\_TLK\_FOSS\_Reference.pdf
+manual located under the "documentation" directory\_.
+
+Build TLK
+=========
+
+To build and execute TLK, follow the instructions from "Building a TLK Device"
+section from Tegra\_BSP\_for\_Android\_TLK\_FOSS\_Reference.pdf manual.
+
+Input parameters to TLK
+=======================
+
+TLK expects the TZDRAM size and a structure containing the boot arguments. BL2
+passes this information to the EL3 software as members of the bl32\_ep\_info
+struct, where bl32\_ep\_info is part of bl31\_params\_t (passed by BL2 in X0)
+
+Example:
+--------
+
+::
+
+ bl32_ep_info->args.arg0 = TZDRAM size available for BL32
+ bl32_ep_info->args.arg1 = unused (used only on Armv7-A)
+ bl32_ep_info->args.arg2 = pointer to boot args
--- /dev/null
+Trusty Dispatcher
+=================
+
+Trusty is a a set of software components, supporting a Trusted Execution
+Environment (TEE) on mobile devices, published and maintained by Google.
+
+Detailed information and build instructions can be found on the Android
+Open Source Project (AOSP) webpage for Trusty hosted at
+https://source.android.com/security/trusty
+
+Boot parameters
+===============
+
+Custom boot parameters can be passed to Trusty by providing a platform
+specific function:
+
+.. code:: c
+
+ void plat_trusty_set_boot_args(aapcs64_params_t *args)
+
+If this function is provided ``args->arg0`` must be set to the memory
+size allocated to trusty. If the platform does not provide this
+function, but defines ``TSP_SEC_MEM_SIZE``, a default implementation
+will pass the memory size from ``TSP_SEC_MEM_SIZE``. ``args->arg1``
+can be set to a platform specific parameter block, and ``args->arg2``
+should then be set to the size of that block.
+
+Supported platforms
+===================
+
+Out of all the platforms supported by Trusted Firmware-A, Trusty is only
+verified and supported by NVIDIA's Tegra SoCs.
--- /dev/null
+Translation Tables Library Design
+=================================
+
+
+
+
+.. contents::
+
+
+This document describes the design of the translation tables library (version 2)
+used by Trusted Firmware-A (TF-A). This library provides APIs to create page
+tables based on a description of the memory layout, as well as setting up system
+registers related to the Memory Management Unit (MMU) and performing the
+required Translation Lookaside Buffer (TLB) maintenance operations.
+
+More specifically, some use cases that this library aims to support are:
+
+#. Statically allocate translation tables and populate them (at run-time) based
+ on a description of the memory layout. The memory layout is typically
+ provided by the platform port as a list of memory regions;
+
+#. Support for generating translation tables pertaining to a different
+ translation regime than the exception level the library code is executing at;
+
+#. Support for dynamic mapping and unmapping of regions, even while the MMU is
+ on. This can be used to temporarily map some memory regions and unmap them
+ later on when no longer needed;
+
+#. Support for non-identity virtual to physical mappings to compress the virtual
+ address space;
+
+#. Support for changing memory attributes of memory regions at run-time.
+
+
+About version 1 and version 2
+-----------------------------
+
+This document focuses on version 2 of the library, whose sources are available
+in the `lib/xlat_tables_v2`_ directory. Version 1 of the library can still be
+found in `lib/xlat_tables`_ directory but it is less flexible and doesn't
+support dynamic mapping. Although potential bug fixes will be applied to both
+versions, future features enhancements will focus on version 2 and might not be
+back-ported to version 1. Therefore, it is recommended to use version 2,
+especially for new platform ports.
+
+However, please note that version 2 is still in active development and is not
+considered stable yet. Hence, compatibility breaks might be introduced.
+
+From this point onwards, this document will implicitly refer to version 2 of the
+library.
+
+
+Design concepts and interfaces
+------------------------------
+
+This section presents some of the key concepts and data structures used in the
+translation tables library.
+
+`mmap` regions
+~~~~~~~~~~~~~~
+
+An ``mmap_region`` is an abstract, concise way to represent a memory region to
+map. It is one of the key interfaces to the library. It is identified by:
+
+- its physical base address;
+- its virtual base address;
+- its size;
+- its attributes;
+- its mapping granularity (optional).
+
+See the ``struct mmap_region`` type in `xlat_tables_v2.h`_.
+
+The user usually provides a list of such mmap regions to map and lets the
+library transpose that in a set of translation tables. As a result, the library
+might create new translation tables, update or split existing ones.
+
+The region attributes specify the type of memory (for example device or cached
+normal memory) as well as the memory access permissions (read-only or
+read-write, executable or not, secure or non-secure, and so on). In the case of
+the EL1&0 translation regime, the attributes also specify whether the region is
+a User region (EL0) or Privileged region (EL1). See the ``MT_xxx`` definitions
+in `xlat_tables_v2.h`_. Note that for the EL1&0 translation regime the Execute
+Never attribute is set simultaneously for both EL1 and EL0.
+
+The granularity controls the translation table level to go down to when mapping
+the region. For example, assuming the MMU has been configured to use a 4KB
+granule size, the library might map a 2MB memory region using either of the two
+following options:
+
+- using a single level-2 translation table entry;
+- using a level-2 intermediate entry to a level-3 translation table (which
+ contains 512 entries, each mapping 4KB).
+
+The first solution potentially requires less translation tables, hence
+potentially less memory. However, if part of this 2MB region is later remapped
+with different memory attributes, the library might need to split the existing
+page tables to refine the mappings. If a single level-2 entry has been used
+here, a level-3 table will need to be allocated on the fly and the level-2
+modified to point to this new level-3 table. This has a performance cost at
+run-time.
+
+If the user knows upfront that such a remapping operation is likely to happen
+then they might enforce a 4KB mapping granularity for this 2MB region from the
+beginning; remapping some of these 4KB pages on the fly then becomes a
+lightweight operation.
+
+The region's granularity is an optional field; if it is not specified the
+library will choose the mapping granularity for this region as it sees fit (more
+details can be found in `The memory mapping algorithm`_ section below).
+
+Translation Context
+~~~~~~~~~~~~~~~~~~~
+
+The library can create or modify translation tables pertaining to a different
+translation regime than the exception level the library code is executing at.
+For example, the library might be used by EL3 software (for instance BL31) to
+create translation tables pertaining to the S-EL1&0 translation regime.
+
+This flexibility comes from the use of *translation contexts*. A *translation
+context* constitutes the superset of information used by the library to track
+the status of a set of translation tables for a given translation regime.
+
+The library internally allocates a default translation context, which pertains
+to the translation regime of the current exception level. Additional contexts
+may be explicitly allocated and initialized using the
+``REGISTER_XLAT_CONTEXT()`` macro. Separate APIs are provided to act either on
+the default translation context or on an alternative one.
+
+To register a translation context, the user must provide the library with the
+following information:
+
+* A name.
+
+ The resulting translation context variable will be called after this name, to
+ which ``_xlat_ctx`` is appended. For example, if the macro name parameter is
+ ``foo``, the context variable name will be ``foo_xlat_ctx``.
+
+* The maximum number of `mmap` regions to map.
+
+ Should account for both static and dynamic regions, if applicable.
+
+* The number of sub-translation tables to allocate.
+
+ Number of translation tables to statically allocate for this context,
+ excluding the initial lookup level translation table, which is always
+ allocated. For example, if the initial lookup level is 1, this parameter would
+ specify the number of level-2 and level-3 translation tables to pre-allocate
+ for this context.
+
+* The size of the virtual address space.
+
+ Size in bytes of the virtual address space to map using this context. This
+ will incidentally determine the number of entries in the initial lookup level
+ translation table : the library will allocate as many entries as is required
+ to map the entire virtual address space.
+
+* The size of the physical address space.
+
+ Size in bytes of the physical address space to map using this context.
+
+The default translation context is internally initialized using information
+coming (for the most part) from platform-specific defines:
+
+- name: hard-coded to ``tf`` ; hence the name of the default context variable is
+ ``tf_xlat_ctx``;
+- number of `mmap` regions: ``MAX_MMAP_REGIONS``;
+- number of sub-translation tables: ``MAX_XLAT_TABLES``;
+- size of the virtual address space: ``PLAT_VIRT_ADDR_SPACE_SIZE``;
+- size of the physical address space: ``PLAT_PHY_ADDR_SPACE_SIZE``.
+
+Please refer to the `Porting Guide`_ for more details about these macros.
+
+
+Static and dynamic memory regions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The library optionally supports dynamic memory mapping. This feature may be
+enabled using the ``PLAT_XLAT_TABLES_DYNAMIC`` platform build flag.
+
+When dynamic memory mapping is enabled, the library categorises mmap regions as
+*static* or *dynamic*.
+
+- *Static regions* are fixed for the lifetime of the system. They can only be
+ added early on, before the translation tables are created and populated. They
+ cannot be removed afterwards.
+
+- *Dynamic regions* can be added or removed any time.
+
+When the dynamic memory mapping feature is disabled, only static regions exist.
+
+The dynamic memory mapping feature may be used to map and unmap transient memory
+areas. This is useful when the user needs to access some memory for a fixed
+period of time, after which the memory may be discarded and reclaimed. For
+example, a memory region that is only required at boot time while the system is
+initializing, or to temporarily share a memory buffer between the normal world
+and trusted world. Note that it is up to the caller to ensure that these regions
+are not accessed concurrently while the regions are being added or removed.
+
+Although this feature provides some level of dynamic memory allocation, this
+does not allow dynamically allocating an arbitrary amount of memory at an
+arbitrary memory location. The user is still required to declare at compile-time
+the limits of these allocations ; the library will deny any mapping request that
+does not fit within this pre-allocated pool of memory.
+
+
+Library APIs
+------------
+
+The external APIs exposed by this library are declared and documented in the
+`xlat_tables_v2.h`_ header file. This should be the reference point for
+getting information about the usage of the different APIs this library
+provides. This section just provides some extra details and clarifications.
+
+Although the ``mmap_region`` structure is a publicly visible type, it is not
+recommended to populate these structures by hand. Instead, wherever APIs expect
+function arguments of type ``mmap_region_t``, these should be constructed using
+the ``MAP_REGION*()`` family of helper macros. This is to limit the risk of
+compatibility breaks, should the ``mmap_region`` structure type evolve in the
+future.
+
+The ``MAP_REGION()`` and ``MAP_REGION_FLAT()`` macros do not allow specifying a
+mapping granularity, which leaves the library implementation free to choose
+it. However, in cases where a specific granularity is required, the
+``MAP_REGION2()`` macro might be used instead.
+
+As explained earlier in this document, when the dynamic mapping feature is
+disabled, there is no notion of dynamic regions. Conceptually, there are only
+static regions. For this reason (and to retain backward compatibility with the
+version 1 of the library), the APIs that map static regions do not embed the
+word *static* in their functions names (for example ``mmap_add_region()``), in
+contrast with the dynamic regions APIs (for example
+``mmap_add_dynamic_region()``).
+
+Although the definition of static and dynamic regions is not based on the state
+of the MMU, the two are still related in some way. Static regions can only be
+added before ``init_xlat_tables()`` is called and ``init_xlat_tables()`` must be
+called while the MMU is still off. As a result, static regions cannot be added
+once the MMU has been enabled. Dynamic regions can be added with the MMU on or
+off. In practice, the usual call flow would look like this:
+
+#. The MMU is initially off.
+
+#. Add some static regions, add some dynamic regions.
+
+#. Initialize translation tables based on the list of mmap regions (using one of
+ the ``init_xlat_tables*()`` APIs).
+
+#. At this point, it is no longer possible to add static regions. Dynamic
+ regions can still be added or removed.
+
+#. Enable the MMU.
+
+#. Dynamic regions can continue to be added or removed.
+
+Because static regions are added early on at boot time and are all in the
+control of the platform initialization code, the ``mmap_add*()`` family of APIs
+are not expected to fail. They do not return any error code.
+
+Nonetheless, these APIs will check upfront whether the region can be
+successfully added before updating the translation context structure. If the
+library detects that there is insufficient memory to meet the request, or that
+the new region will overlap another one in an invalid way, or if any other
+unexpected error is encountered, they will print an error message on the UART.
+Additionally, when asserts are enabled (typically in debug builds), an assertion
+will be triggered. Otherwise, the function call will just return straight away,
+without adding the offending memory region.
+
+
+Library limitations
+-------------------
+
+Dynamic regions are not allowed to overlap each other. Static regions are
+allowed to overlap as long as one of them is fully contained inside the other
+one. This is allowed for backwards compatibility with the previous behaviour in
+the version 1 of the library.
+
+
+Implementation details
+----------------------
+
+Code structure
+~~~~~~~~~~~~~~
+
+The library is divided into 4 modules:
+
+- **Core module**
+
+ Provides the main functionality of the library, such as the initialization of
+ translation tables contexts and mapping/unmapping memory regions. This module
+ provides functions such as ``mmap_add_region_ctx`` that let the caller specify
+ the translation tables context affected by them.
+
+ See `xlat_tables_core.c`_.
+
+- **Active context module**
+
+ Instantiates the context that is used by the current BL image and provides
+ helpers to manipulate it, abstracting it from the rest of the code.
+ This module provides functions such as ``mmap_add_region``, that directly
+ affect the BL image using them.
+
+ See `xlat_tables_context.c`_.
+
+- **Utilities module**
+
+ Provides additional functionality like debug print of the current state of the
+ translation tables and helpers to query memory attributes and to modify them.
+
+ See `xlat_tables_utils.c`_.
+
+- **Architectural module**
+
+ Provides functions that are dependent on the current execution state
+ (AArch32/AArch64), such as the functions used for TLB invalidation, setup the
+ MMU, or calculate the Physical Address Space size. They do not need a
+ translation context to work on.
+
+ See `aarch32/xlat_tables_arch.c`_ and `aarch64/xlat_tables_arch.c`_.
+
+From mmap regions to translation tables
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A translation context contains a list of ``mmap_region_t``, which holds the
+information of all the regions that are mapped at any given time. Whenever there
+is a request to map (resp. unmap) a memory region, it is added to (resp. removed
+from) the ``mmap_region_t`` list.
+
+The mmap regions list is a conceptual way to represent the memory layout. At
+some point, the library has to convert this information into actual translation
+tables to program into the MMU.
+
+Before the ``init_xlat_tables()`` API is called, the library only acts on the
+mmap regions list. Adding a static or dynamic region at this point through one
+of the ``mmap_add*()`` APIs does not affect the translation tables in any way,
+they only get registered in the internal mmap region list. It is only when the
+user calls the ``init_xlat_tables()`` that the translation tables are populated
+in memory based on the list of mmap regions registered so far. This is an
+optimization that allows creation of the initial set of translation tables in
+one go, rather than having to edit them every time while the MMU is disabled.
+
+After the ``init_xlat_tables()`` API has been called, only dynamic regions can
+be added. Changes to the translation tables (as well as the mmap regions list)
+will take effect immediately.
+
+The memory mapping algorithm
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The mapping function is implemented as a recursive algorithm. It is however
+bound by the level of depth of the translation tables (the Armv8-A architecture
+allows up to 4 lookup levels).
+
+By default [#granularity-ref]_, the algorithm will attempt to minimize the
+number of translation tables created to satisfy the user's request. It will
+favour mapping a region using the biggest possible blocks, only creating a
+sub-table if it is strictly necessary. This is to reduce the memory footprint of
+the firmware.
+
+The most common reason for needing a sub-table is when a specific mapping
+requires a finer granularity. Misaligned regions also require a finer
+granularity than what the user may had originally expected, using a lot more
+memory than expected. The reason is that all levels of translation are
+restricted to address translations of the same granularity as the size of the
+blocks of that level. For example, for a 4 KiB page size, a level 2 block entry
+can only translate up to a granularity of 2 MiB. If the Physical Address is not
+aligned to 2 MiB then additional level 3 tables are also needed.
+
+Note that not every translation level allows any type of descriptor. Depending
+on the page size, levels 0 and 1 of translation may only allow table
+descriptors. If a block entry could be able to describe a translation, but that
+level does not allow block descriptors, a table descriptor will have to be used
+instead, as well as additional tables at the next level.
+
+|Alignment Example|
+
+The mmap regions are sorted in a way that simplifies the code that maps
+them. Even though this ordering is only strictly needed for overlapping static
+regions, it must also be applied for dynamic regions to maintain a consistent
+order of all regions at all times. As each new region is mapped, existing
+entries in the translation tables are checked to ensure consistency. Please
+refer to the comments in the source code of the core module for more details
+about the sorting algorithm in use.
+
+.. [#granularity-ref] That is, when mmap regions do not enforce their mapping
+ granularity.
+
+TLB maintenance operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The library takes care of performing TLB maintenance operations when required.
+For example, when the user requests removing a dynamic region, the library
+invalidates all TLB entries associated to that region to ensure that these
+changes are visible to subsequent execution, including speculative execution,
+that uses the changed translation table entries.
+
+A counter-example is the initialization of translation tables. In this case,
+explicit TLB maintenance is not required. The Armv8-A architecture guarantees
+that all TLBs are disabled from reset and their contents have no effect on
+address translation at reset [#tlb-reset-ref]_. Therefore, the TLBs invalidation
+is deferred to the ``enable_mmu*()`` family of functions, just before the MMU is
+turned on.
+
+TLB invalidation is not required when adding dynamic regions either. Dynamic
+regions are not allowed to overlap existing memory region. Therefore, if the
+dynamic mapping request is deemed legitimate, it automatically concerns memory
+that was not mapped in this translation regime and the library will have
+initialized its corresponding translation table entry to an invalid
+descriptor. Given that the TLBs are not architecturally permitted to hold any
+invalid translation table entry [#tlb-no-invalid-entry]_, this means that this
+mapping cannot be cached in the TLBs.
+
+.. [#tlb-reset-ref] See section D4.9 `Translation Lookaside Buffers (TLBs)`, subsection `TLB behavior at reset` in Armv8-A, rev C.a.
+.. [#tlb-no-invalid-entry] See section D4.10.1 `General TLB maintenance requirements` in Armv8-A, rev C.a.
+
+--------------
+
+*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _lib/xlat_tables_v2: ../../lib/xlat_tables_v2
+.. _lib/xlat_tables: ../../lib/xlat_tables
+.. _xlat_tables_v2.h: ../../include/lib/xlat_tables/xlat_tables_v2.h
+.. _xlat_tables_context.c: ../../lib/xlat_tables_v2/xlat_tables_context.c
+.. _xlat_tables_core.c: ../../lib/xlat_tables_v2/xlat_tables_core.c
+.. _xlat_tables_utils.c: ../../lib/xlat_tables_v2/xlat_tables_utils.c
+.. _aarch32/xlat_tables_arch.c: ../../lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+.. _aarch64/xlat_tables_arch.c: ../../lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+.. _Porting Guide: ../getting_started/porting-guide.rst
+.. |Alignment Example| image:: ../diagrams/xlat_align.png?raw=true
+++ /dev/null
-Trusted Firmware-A Documentation Contents
-=========================================
-
-This document serves as a list of the documentation that is included with the
-Trusted Firmware-A source.
-
-Introduction
-------------
-
-`About Trusted Firmware-A`_
-
-Getting Started
----------------
-
-`Frequently-Asked Questions (FAQ)`_
-
-`Image Terminology`_
-
-`Porting Guide`_
-
-`User Guide`_
-
-Contributing
-------------
-
-`Coding Style and Guidelines`_
-
-`Contributor Acknowledgements`_
-
-`Contributor's Guide`_
-
-`License`_
-
-`Maintainers`_
-
-Processes and Policies
-----------------------
-
-`Platform Compatibility Policy`_
-
-`Release Processes`_
-
-Secure Payload Dispatch
------------------------
-
-`OP-TEE Dispatcher`_
-
-`Trusted Little Kernel (TLK) Dispatcher`_
-
-`Trusty Dispatcher`_
-
-System Design and Components
-----------------------------
-
-`Arm CPU Specific Build Macros`_
-
-`Arm SiP Services`_
-
-`Authentication Framework & Chain of Trust`_
-
-`CPU Reset`_
-
-`EL3 Runtime Service Writer’s Guide`_
-
-`Exception Handling Framework`_
-
-`Firmware Design Overview`_
-
-`Firmware Update (FWU)`_
-
-`Interrupt Management Framework`_
-
-`Library at ROM`_
-
-`Platform Interrupt Controller API`_
-
-`PSCI Library Integration Guide for Armv8-A AArch32 systems`_
-
-`PSCI Power Domain Tree design`_
-
-`Reliability, Availability, and Serviceability (RAS) Extensions`_
-
-`Secure Partition Manager`_
-
-`Software Delegated Exception Interface`_
-
-`Translation (XLAT) Tables Library`_
-
-`Trusted Board Boot Design Guide`_
-
-Performance and Testing
------------------------
-
-`PSCI Performance Measurements on Arm Juno Development Platform`_
-
-Security and Advisories
------------------------
-
-`Security Processes`_
-
-`TFV-1`_
-
-`TFV-2`_
-
-`TFV-3`_
-
-`TFV-4`_
-
-`TFV-5`_
-
-`TFV-6`_
-
-`TFV-7`_
-
-`TFV-8`_
-
-Other Documents
----------------
-
-`Change Log`_
-
-.. _About Trusted Firmware-A: ../readme.rst
-.. _Frequently-Asked Questions (FAQ): ./frequently-asked-questions.rst
-.. _Image Terminology: ./image-terminology.rst
-.. _Porting Guide: ./porting-guide.rst
-.. _User Guide: ./user-guide.rst
-.. _Coding Style and Guidelines: ./coding-guidelines.rst
-.. _Contributor Acknowledgements: ../acknowledgements.rst
-.. _`Contributor's Guide`: ../contributing.rst
-.. _License: ../license.rst
-.. _Maintainers: ../maintainers.rst
-.. _Platform Compatibility Policy: ./platform-compatibility-policy.rst
-.. _Release Processes: ./release-information.rst
-.. _Arm SiP Services: ./arm-sip-service.rst
-.. _Exception Handling Framework: ./exception-handling.rst
-.. _Firmware Update (FWU): ./firmware-update.rst
-.. _Interrupt Management Framework: ./interrupt-framework-design.rst
-.. _Library at ROM: ./romlib-design.rst
-.. _Platform Interrupt Controller API: ./platform-interrupt-controller-API.rst
-.. _`Reliability, Availability, and Serviceability (RAS) Extensions`: ./ras.rst
-.. _Secure Partition Manager: ./secure-partition-manager-design.rst
-.. _Software Delegated Exception Interface: ./sdei.rst
-.. _Translation (XLAT) Tables Library: ./xlat-tables-lib-v2-design.rst
-.. _OP-TEE Dispatcher: ./spd/optee-dispatcher.rst
-.. _Trusted Little Kernel (TLK) Dispatcher: ./spd/tlk-dispatcher.rst
-.. _Trusty Dispatcher: ./spd/trusty-dispatcher.rst
-.. _Arm CPU Specific Build Macros: ./cpu-specific-build-macros.rst
-.. _`Authentication Framework & Chain of Trust`: ./auth-framework.rst
-.. _CPU Reset: ./reset-design.rst
-.. _`EL3 Runtime Service Writer’s Guide`: ./rt-svc-writers-guide.rst
-.. _Firmware Design Overview: ./firmware-design.rst
-.. _PSCI Library Integration Guide for Armv8-A AArch32 systems: ./psci-lib-integration-guide.rst
-.. _PSCI Power Domain Tree design: ./psci-pd-tree.rst
-.. _Trusted Board Boot Design Guide: ./trusted-board-boot.rst
-.. _PSCI Performance Measurements on Arm Juno Development Platform: ./psci-performance-juno.rst
-.. _Security Processes: ./security-center.rst
-.. _Change Log: ./change-log.rst
-.. _TFV-1: ./security_advisories/security-advisory-tfv-1.rst
-.. _TFV-2: ./security_advisories/security-advisory-tfv-2.rst
-.. _TFV-3: ./security_advisories/security-advisory-tfv-3.rst
-.. _TFV-4: ./security_advisories/security-advisory-tfv-4.rst
-.. _TFV-5: ./security_advisories/security-advisory-tfv-5.rst
-.. _TFV-6: ./security_advisories/security-advisory-tfv-6.rst
-.. _TFV-7: ./security_advisories/security-advisory-tfv-7.rst
-.. _TFV-8: ./security_advisories/security-advisory-tfv-8.rst
+++ /dev/null
-Arm CPU Specific Build Macros
-=============================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-This document describes the various build options present in the CPU specific
-operations framework to enable errata workarounds and to enable optimizations
-for a specific CPU on a platform.
-
-Security Vulnerability Workarounds
-----------------------------------
-
-TF-A exports a series of build flags which control which security
-vulnerability workarounds should be applied at runtime.
-
-- ``WORKAROUND_CVE_2017_5715``: Enables the security workaround for
- `CVE-2017-5715`_. This flag can be set to 0 by the platform if none
- of the PEs in the system need the workaround. Setting this flag to 0 provides
- no performance benefit for non-affected platforms, it just helps to comply
- with the recommendation in the spec regarding workaround discovery.
- Defaults to 1.
-
-- ``WORKAROUND_CVE_2018_3639``: Enables the security workaround for
- `CVE-2018-3639`_. Defaults to 1. The TF-A project recommends to keep
- the default value of 1 even on platforms that are unaffected by
- CVE-2018-3639, in order to comply with the recommendation in the spec
- regarding workaround discovery.
-
-- ``DYNAMIC_WORKAROUND_CVE_2018_3639``: Enables dynamic mitigation for
- `CVE-2018-3639`_. This build option should be set to 1 if the target
- platform contains at least 1 CPU that requires dynamic mitigation.
- Defaults to 0.
-
-CPU Errata Workarounds
-----------------------
-
-TF-A exports a series of build flags which control the errata workarounds that
-are applied to each CPU by the reset handler. The errata details can be found
-in the CPU specific errata documents published by Arm:
-
-- `Cortex-A53 MPCore Software Developers Errata Notice`_
-- `Cortex-A57 MPCore Software Developers Errata Notice`_
-- `Cortex-A72 MPCore Software Developers Errata Notice`_
-
-The errata workarounds are implemented for a particular revision or a set of
-processor revisions. This is checked by the reset handler at runtime. Each
-errata workaround is identified by its ``ID`` as specified in the processor's
-errata notice document. The format of the define used to enable/disable the
-errata workaround is ``ERRATA_<Processor name>_<ID>``, where the ``Processor name``
-is for example ``A57`` for the ``Cortex_A57`` CPU.
-
-Refer to the section *CPU errata status reporting* in
-`Firmware Design guide`_ for information on how to write errata workaround
-functions.
-
-All workarounds are disabled by default. The platform is responsible for
-enabling these workarounds according to its requirement by defining the
-errata workaround build flags in the platform specific makefile. In case
-these workarounds are enabled for the wrong CPU revision then the errata
-workaround is not applied. In the DEBUG build, this is indicated by
-printing a warning to the crash console.
-
-In the current implementation, a platform which has more than 1 variant
-with different revisions of a processor has no runtime mechanism available
-for it to specify which errata workarounds should be enabled or not.
-
-The value of the build flags is 0 by default, that is, disabled. A value of 1
-will enable it.
-
-For Cortex-A9, the following errata build flags are defined :
-
-- ``ERRATA_A9_794073``: This applies errata 794073 workaround to Cortex-A9
- CPU. This needs to be enabled for all revisions of the CPU.
-
-For Cortex-A15, the following errata build flags are defined :
-
-- ``ERRATA_A15_816470``: This applies errata 816470 workaround to Cortex-A15
- CPU. This needs to be enabled only for revision >= r3p0 of the CPU.
-
-- ``ERRATA_A15_827671``: This applies errata 827671 workaround to Cortex-A15
- CPU. This needs to be enabled only for revision >= r3p0 of the CPU.
-
-For Cortex-A17, the following errata build flags are defined :
-
-- ``ERRATA_A17_852421``: This applies errata 852421 workaround to Cortex-A17
- CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
-
-- ``ERRATA_A17_852423``: This applies errata 852423 workaround to Cortex-A17
- CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
-
-For Cortex-A35, the following errata build flags are defined :
-
-- ``ERRATA_A35_855472``: This applies errata 855472 workaround to Cortex-A35
- CPUs. This needs to be enabled only for revision r0p0 of Cortex-A35.
-
-For Cortex-A53, the following errata build flags are defined :
-
-- ``ERRATA_A53_819472``: This applies errata 819472 workaround to all
- CPUs. This needs to be enabled only for revision <= r0p1 of Cortex-A53.
-
-- ``ERRATA_A53_824069``: This applies errata 824069 workaround to all
- CPUs. This needs to be enabled only for revision <= r0p2 of Cortex-A53.
-
-- ``ERRATA_A53_826319``: This applies errata 826319 workaround to Cortex-A53
- CPU. This needs to be enabled only for revision <= r0p2 of the CPU.
-
-- ``ERRATA_A53_827319``: This applies errata 827319 workaround to all
- CPUs. This needs to be enabled only for revision <= r0p2 of Cortex-A53.
-
-- ``ERRATA_A53_835769``: This applies erratum 835769 workaround at compile and
- link time to Cortex-A53 CPU. This needs to be enabled for some variants of
- revision <= r0p4. This workaround can lead the linker to create ``*.stub``
- sections.
-
-- ``ERRATA_A53_836870``: This applies errata 836870 workaround to Cortex-A53
- CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From
- r0p4 and onwards, this errata is enabled by default in hardware.
-
-- ``ERRATA_A53_843419``: This applies erratum 843419 workaround at link time
- to Cortex-A53 CPU. This needs to be enabled for some variants of revision
- <= r0p4. This workaround can lead the linker to emit ``*.stub`` sections
- which are 4kB aligned.
-
-- ``ERRATA_A53_855873``: This applies errata 855873 workaround to Cortex-A53
- CPUs. Though the erratum is present in every revision of the CPU,
- this workaround is only applied to CPUs from r0p3 onwards, which feature
- a chicken bit in CPUACTLR_EL1 to enable a hardware workaround.
- Earlier revisions of the CPU have other errata which require the same
- workaround in software, so they should be covered anyway.
-
-For Cortex-A55, the following errata build flags are defined :
-
-- ``ERRATA_A55_768277``: This applies errata 768277 workaround to Cortex-A55
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A55_778703``: This applies errata 778703 workaround to Cortex-A55
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A55_798797``: This applies errata 798797 workaround to Cortex-A55
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A55_846532``: This applies errata 846532 workaround to Cortex-A55
- CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
-
-- ``ERRATA_A55_903758``: This applies errata 903758 workaround to Cortex-A55
- CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
-
-For Cortex-A57, the following errata build flags are defined :
-
-- ``ERRATA_A57_806969``: This applies errata 806969 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A57_813419``: This applies errata 813419 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A57_813420``: This applies errata 813420 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A57_814670``: This applies errata 814670 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A57_817169``: This applies errata 817169 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
-
-- ``ERRATA_A57_826974``: This applies errata 826974 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
-
-- ``ERRATA_A57_826977``: This applies errata 826977 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
-
-- ``ERRATA_A57_828024``: This applies errata 828024 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
-
-- ``ERRATA_A57_829520``: This applies errata 829520 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
-
-- ``ERRATA_A57_833471``: This applies errata 833471 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
-
-- ``ERRATA_A57_859972``: This applies errata 859972 workaround to Cortex-A57
- CPU. This needs to be enabled only for revision <= r1p3 of the CPU.
-
-
-For Cortex-A72, the following errata build flags are defined :
-
-- ``ERRATA_A72_859971``: This applies errata 859971 workaround to Cortex-A72
- CPU. This needs to be enabled only for revision <= r0p3 of the CPU.
-
-For Cortex-A73, the following errata build flags are defined :
-
-- ``ERRATA_A73_852427``: This applies errata 852427 workaround to Cortex-A73
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A73_855423``: This applies errata 855423 workaround to Cortex-A73
- CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
-
-For Cortex-A75, the following errata build flags are defined :
-
-- ``ERRATA_A75_764081``: This applies errata 764081 workaround to Cortex-A75
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-- ``ERRATA_A75_790748``: This applies errata 790748 workaround to Cortex-A75
- CPU. This needs to be enabled only for revision r0p0 of the CPU.
-
-For Cortex-A76, the following errata build flags are defined :
-
-- ``ERRATA_A76_1073348``: This applies errata 1073348 workaround to Cortex-A76
- CPU. This needs to be enabled only for revision <= r1p0 of the CPU.
-
-- ``ERRATA_A76_1130799``: This applies errata 1130799 workaround to Cortex-A76
- CPU. This needs to be enabled only for revision <= r2p0 of the CPU.
-
-- ``ERRATA_A76_1220197``: This applies errata 1220197 workaround to Cortex-A76
- CPU. This needs to be enabled only for revision <= r2p0 of the CPU.
-
-- ``ERRATA_A76_1257314``: This applies errata 1257314 workaround to Cortex-A76
- CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
-
-- ``ERRATA_A76_1262606``: This applies errata 1262606 workaround to Cortex-A76
- CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
-
-- ``ERRATA_A76_1262888``: This applies errata 1262888 workaround to Cortex-A76
- CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
-
-- ``ERRATA_A76_1275112``: This applies errata 1275112 workaround to Cortex-A76
- CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
-
-DSU Errata Workarounds
-----------------------
-
-Similar to CPU errata, TF-A also implements workarounds for DSU (DynamIQ
-Shared Unit) errata. The DSU errata details can be found in the respective Arm
-documentation:
-
-- `Arm DSU Software Developers Errata Notice`_.
-
-Each erratum is identified by an ``ID``, as defined in the DSU errata notice
-document. Thus, the build flags which enable/disable the errata workarounds
-have the format ``ERRATA_DSU_<ID>``. The implementation and application logic
-of DSU errata workarounds are similar to `CPU errata workarounds`_.
-
-For DSU errata, the following build flags are defined:
-
-- ``ERRATA_DSU_798953``: This applies errata 798953 workaround for the
- affected DSU configurations. This errata applies only for those DSUs that
- revision is r0p0 (on r0p1 it is fixed). However, please note that this
- workaround results in increased DSU power consumption on idle.
-
-- ``ERRATA_DSU_936184``: This applies errata 936184 workaround for the
- affected DSU configurations. This errata applies only for those DSUs that
- contain the ACP interface **and** the DSU revision is older than r2p0 (on
- r2p0 it is fixed). However, please note that this workaround results in
- increased DSU power consumption on idle.
-
-CPU Specific optimizations
---------------------------
-
-This section describes some of the optimizations allowed by the CPU micro
-architecture that can be enabled by the platform as desired.
-
-- ``SKIP_A57_L1_FLUSH_PWR_DWN``: This flag enables an optimization in the
- Cortex-A57 cluster power down sequence by not flushing the Level 1 data
- cache. The L1 data cache and the L2 unified cache are inclusive. A flush
- of the L2 by set/way flushes any dirty lines from the L1 as well. This
- is a known safe deviation from the Cortex-A57 TRM defined power down
- sequence. Each Cortex-A57 based platform must make its own decision on
- whether to use the optimization.
-
-- ``A53_DISABLE_NON_TEMPORAL_HINT``: This flag disables the cache non-temporal
- hint. The LDNP/STNP instructions as implemented on Cortex-A53 do not behave
- in a way most programmers expect, and will most probably result in a
- significant speed degradation to any code that employs them. The Armv8-A
- architecture (see Arm DDI 0487A.h, section D3.4.3) allows cores to ignore
- the non-temporal hint and treat LDNP/STNP as LDP/STP instead. Enabling this
- flag enforces this behaviour. This needs to be enabled only for revisions
- <= r0p3 of the CPU and is enabled by default.
-
-- ``A57_DISABLE_NON_TEMPORAL_HINT``: This flag has the same behaviour as
- ``A53_DISABLE_NON_TEMPORAL_HINT`` but for Cortex-A57. This needs to be
- enabled only for revisions <= r1p2 of the CPU and is enabled by default,
- as recommended in section "4.7 Non-Temporal Loads/Stores" of the
- `Cortex-A57 Software Optimization Guide`_.
-
---------------
-
-*Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
-.. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
-.. _Cortex-A53 MPCore Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm048406/index.html
-.. _Cortex-A57 MPCore Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm049219/index.html
-.. _Cortex-A72 MPCore Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm012079/index.html
-.. _Firmware Design guide: firmware-design.rst
-.. _Cortex-A57 Software Optimization Guide: http://infocenter.arm.com/help/topic/com.arm.doc.uan0015b/Cortex_A57_Software_Optimization_Guide_external.pdf
-.. _Arm DSU Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm138168/index.html
--- /dev/null
+Abstracting a Chain of Trust
+============================
+
+
+
+
+.. contents::
+
+The aim of this document is to describe the authentication framework
+implemented in Trusted Firmware-A (TF-A). This framework fulfills the
+following requirements:
+
+#. It should be possible for a platform port to specify the Chain of Trust in
+ terms of certificate hierarchy and the mechanisms used to verify a
+ particular image/certificate.
+
+#. The framework should distinguish between:
+
+ - The mechanism used to encode and transport information, e.g. DER encoded
+ X.509v3 certificates to ferry Subject Public Keys, hashes and non-volatile
+ counters.
+
+ - The mechanism used to verify the transported information i.e. the
+ cryptographic libraries.
+
+The framework has been designed following a modular approach illustrated in the
+next diagram:
+
+::
+
+ +---------------+---------------+------------+
+ | Trusted | Trusted | Trusted |
+ | Firmware | Firmware | Firmware |
+ | Generic | IO Framework | Platform |
+ | Code i.e. | (IO) | Port |
+ | BL1/BL2 (GEN) | | (PP) |
+ +---------------+---------------+------------+
+ ^ ^ ^
+ | | |
+ v v v
+ +-----------+ +-----------+ +-----------+
+ | | | | | Image |
+ | Crypto | | Auth | | Parser |
+ | Module |<->| Module |<->| Module |
+ | (CM) | | (AM) | | (IPM) |
+ | | | | | |
+ +-----------+ +-----------+ +-----------+
+ ^ ^
+ | |
+ v v
+ +----------------+ +-----------------+
+ | Cryptographic | | Image Parser |
+ | Libraries (CL) | | Libraries (IPL) |
+ +----------------+ +-----------------+
+ | |
+ | |
+ | |
+ v v
+ +-----------------+
+ | Misc. Libs e.g. |
+ | ASN.1 decoder |
+ | |
+ +-----------------+
+
+ DIAGRAM 1.
+
+This document describes the inner details of the authentication framework and
+the abstraction mechanisms available to specify a Chain of Trust.
+
+Framework design
+----------------
+
+This section describes some aspects of the framework design and the rationale
+behind them. These aspects are key to verify a Chain of Trust.
+
+Chain of Trust
+~~~~~~~~~~~~~~
+
+A CoT is basically a sequence of authentication images which usually starts with
+a root of trust and culminates in a single data image. The following diagram
+illustrates how this maps to a CoT for the BL31 image described in the
+`TBBR-Client specification`_.
+
+::
+
+ +------------------+ +-------------------+
+ | ROTPK/ROTPK Hash |------>| Trusted Key |
+ +------------------+ | Certificate |
+ | (Auth Image) |
+ /+-------------------+
+ / |
+ / |
+ / |
+ / |
+ L v
+ +------------------+ +-------------------+
+ | Trusted World |------>| BL31 Key |
+ | Public Key | | Certificate |
+ +------------------+ | (Auth Image) |
+ +-------------------+
+ / |
+ / |
+ / |
+ / |
+ / v
+ +------------------+ L +-------------------+
+ | BL31 Content |------>| BL31 Content |
+ | Certificate PK | | Certificate |
+ +------------------+ | (Auth Image) |
+ +-------------------+
+ / |
+ / |
+ / |
+ / |
+ / v
+ +------------------+ L +-------------------+
+ | BL31 Hash |------>| BL31 Image |
+ | | | (Data Image) |
+ +------------------+ | |
+ +-------------------+
+
+ DIAGRAM 2.
+
+The root of trust is usually a public key (ROTPK) that has been burnt in the
+platform and cannot be modified.
+
+Image types
+~~~~~~~~~~~
+
+Images in a CoT are categorised as authentication and data images. An
+authentication image contains information to authenticate a data image or
+another authentication image. A data image is usually a boot loader binary, but
+it could be any other data that requires authentication.
+
+Component responsibilities
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For every image in a Chain of Trust, the following high level operations are
+performed to verify it:
+
+#. Allocate memory for the image either statically or at runtime.
+
+#. Identify the image and load it in the allocated memory.
+
+#. Check the integrity of the image as per its type.
+
+#. Authenticate the image as per the cryptographic algorithms used.
+
+#. If the image is an authentication image, extract the information that will
+ be used to authenticate the next image in the CoT.
+
+In Diagram 1, each component is responsible for one or more of these operations.
+The responsibilities are briefly described below.
+
+TF-A Generic code and IO framework (GEN/IO)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These components are responsible for initiating the authentication process for a
+particular image in BL1 or BL2. For each BL image that requires authentication,
+the Generic code asks recursively the Authentication module what is the parent
+image until either an authenticated image or the ROT is reached. Then the
+Generic code calls the IO framework to load the image and calls the
+Authentication module to authenticate it, following the CoT from ROT to Image.
+
+TF-A Platform Port (PP)
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The platform is responsible for:
+
+#. Specifying the CoT for each image that needs to be authenticated. Details of
+ how a CoT can be specified by the platform are explained later. The platform
+ also specifies the authentication methods and the parsing method used for
+ each image.
+
+#. Statically allocating memory for each parameter in each image which is
+ used for verifying the CoT, e.g. memory for public keys, hashes etc.
+
+#. Providing the ROTPK or a hash of it.
+
+#. Providing additional information to the IPM to enable it to identify and
+ extract authentication parameters contained in an image, e.g. if the
+ parameters are stored as X509v3 extensions, the corresponding OID must be
+ provided.
+
+#. Fulfill any other memory requirements of the IPM and the CM (not currently
+ described in this document).
+
+#. Export functions to verify an image which uses an authentication method that
+ cannot be interpreted by the CM, e.g. if an image has to be verified using a
+ NV counter, then the value of the counter to compare with can only be
+ provided by the platform.
+
+#. Export a custom IPM if a proprietary image format is being used (described
+ later).
+
+Authentication Module (AM)
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+It is responsible for:
+
+#. Providing the necessary abstraction mechanisms to describe a CoT. Amongst
+ other things, the authentication and image parsing methods must be specified
+ by the PP in the CoT.
+
+#. Verifying the CoT passed by GEN by utilising functionality exported by the
+ PP, IPM and CM.
+
+#. Tracking which images have been verified. In case an image is a part of
+ multiple CoTs then it should be verified only once e.g. the Trusted World
+ Key Certificate in the TBBR-Client spec. contains information to verify
+ SCP_BL2, BL31, BL32 each of which have a separate CoT. (This
+ responsibility has not been described in this document but should be
+ trivial to implement).
+
+#. Reusing memory meant for a data image to verify authentication images e.g.
+ in the CoT described in Diagram 2, each certificate can be loaded and
+ verified in the memory reserved by the platform for the BL31 image. By the
+ time BL31 (the data image) is loaded, all information to authenticate it
+ will have been extracted from the parent image i.e. BL31 content
+ certificate. It is assumed that the size of an authentication image will
+ never exceed the size of a data image. It should be possible to verify this
+ at build time using asserts.
+
+Cryptographic Module (CM)
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The CM is responsible for providing an API to:
+
+#. Verify a digital signature.
+#. Verify a hash.
+
+The CM does not include any cryptography related code, but it relies on an
+external library to perform the cryptographic operations. A Crypto-Library (CL)
+linking the CM and the external library must be implemented. The following
+functions must be provided by the CL:
+
+.. code:: c
+
+ void (*init)(void);
+ int (*verify_signature)(void *data_ptr, unsigned int data_len,
+ void *sig_ptr, unsigned int sig_len,
+ void *sig_alg, unsigned int sig_alg_len,
+ void *pk_ptr, unsigned int pk_len);
+ int (*verify_hash)(void *data_ptr, unsigned int data_len,
+ void *digest_info_ptr, unsigned int digest_info_len);
+
+These functions are registered in the CM using the macro:
+
+.. code:: c
+
+ REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash);
+
+``_name`` must be a string containing the name of the CL. This name is used for
+debugging purposes.
+
+Image Parser Module (IPM)
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The IPM is responsible for:
+
+#. Checking the integrity of each image loaded by the IO framework.
+#. Extracting parameters used for authenticating an image based upon a
+ description provided by the platform in the CoT descriptor.
+
+Images may have different formats (for example, authentication images could be
+x509v3 certificates, signed ELF files or any other platform specific format).
+The IPM allows to register an Image Parser Library (IPL) for every image format
+used in the CoT. This library must implement the specific methods to parse the
+image. The IPM obtains the image format from the CoT and calls the right IPL to
+check the image integrity and extract the authentication parameters.
+
+See Section "Describing the image parsing methods" for more details about the
+mechanism the IPM provides to define and register IPLs.
+
+Authentication methods
+~~~~~~~~~~~~~~~~~~~~~~
+
+The AM supports the following authentication methods:
+
+#. Hash
+#. Digital signature
+
+The platform may specify these methods in the CoT in case it decides to define
+a custom CoT instead of reusing a predefined one.
+
+If a data image uses multiple methods, then all the methods must be a part of
+the same CoT. The number and type of parameters are method specific. These
+parameters should be obtained from the parent image using the IPM.
+
+#. Hash
+
+ Parameters:
+
+ #. A pointer to data to hash
+ #. Length of the data
+ #. A pointer to the hash
+ #. Length of the hash
+
+ The hash will be represented by the DER encoding of the following ASN.1
+ type:
+
+ ::
+
+ DigestInfo ::= SEQUENCE {
+ digestAlgorithm DigestAlgorithmIdentifier,
+ digest Digest
+ }
+
+ This ASN.1 structure makes it possible to remove any assumption about the
+ type of hash algorithm used as this information accompanies the hash. This
+ should allow the Cryptography Library (CL) to support multiple hash
+ algorithm implementations.
+
+#. Digital Signature
+
+ Parameters:
+
+ #. A pointer to data to sign
+ #. Length of the data
+ #. Public Key Algorithm
+ #. Public Key value
+ #. Digital Signature Algorithm
+ #. Digital Signature value
+
+ The Public Key parameters will be represented by the DER encoding of the
+ following ASN.1 type:
+
+ ::
+
+ SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier{PUBLIC-KEY,{PublicKeyAlgorithms}},
+ subjectPublicKey BIT STRING }
+
+ The Digital Signature Algorithm will be represented by the DER encoding of
+ the following ASN.1 types.
+
+ ::
+
+ AlgorithmIdentifier {ALGORITHM:IOSet } ::= SEQUENCE {
+ algorithm ALGORITHM.&id({IOSet}),
+ parameters ALGORITHM.&Type({IOSet}{@algorithm}) OPTIONAL
+ }
+
+ The digital signature will be represented by:
+
+ ::
+
+ signature ::= BIT STRING
+
+The authentication framework will use the image descriptor to extract all the
+information related to authentication.
+
+Specifying a Chain of Trust
+---------------------------
+
+A CoT can be described as a set of image descriptors linked together in a
+particular order. The order dictates the sequence in which they must be
+verified. Each image has a set of properties which allow the AM to verify it.
+These properties are described below.
+
+The PP is responsible for defining a single or multiple CoTs for a data image.
+Unless otherwise specified, the data structures described in the following
+sections are populated by the PP statically.
+
+Describing the image parsing methods
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The parsing method refers to the format of a particular image. For example, an
+authentication image that represents a certificate could be in the X.509v3
+format. A data image that represents a boot loader stage could be in raw binary
+or ELF format. The IPM supports three parsing methods. An image has to use one
+of the three methods described below. An IPL is responsible for interpreting a
+single parsing method. There has to be one IPL for every method used by the
+platform.
+
+#. Raw format: This format is effectively a nop as an image using this method
+ is treated as being in raw binary format e.g. boot loader images used by
+ TF-A. This method should only be used by data images.
+
+#. X509V3 method: This method uses industry standards like X.509 to represent
+ PKI certificates (authentication images). It is expected that open source
+ libraries will be available which can be used to parse an image represented
+ by this method. Such libraries can be used to write the corresponding IPL
+ e.g. the X.509 parsing library code in mbed TLS.
+
+#. Platform defined method: This method caters for platform specific
+ proprietary standards to represent authentication or data images. For
+ example, The signature of a data image could be appended to the data image
+ raw binary. A header could be prepended to the combined blob to specify the
+ extents of each component. The platform will have to implement the
+ corresponding IPL to interpret such a format.
+
+The following enum can be used to define these three methods.
+
+.. code:: c
+
+ typedef enum img_type_enum {
+ IMG_RAW, /* Binary image */
+ IMG_PLAT, /* Platform specific format */
+ IMG_CERT, /* X509v3 certificate */
+ IMG_MAX_TYPES,
+ } img_type_t;
+
+An IPL must provide functions with the following prototypes:
+
+.. code:: c
+
+ void init(void);
+ int check_integrity(void *img, unsigned int img_len);
+ int get_auth_param(const auth_param_type_desc_t *type_desc,
+ void *img, unsigned int img_len,
+ void **param, unsigned int *param_len);
+
+An IPL for each type must be registered using the following macro:
+
+::
+
+ REGISTER_IMG_PARSER_LIB(_type, _name, _init, _check_int, _get_param)
+
+- ``_type``: one of the types described above.
+- ``_name``: a string containing the IPL name for debugging purposes.
+- ``_init``: initialization function pointer.
+- ``_check_int``: check image integrity function pointer.
+- ``_get_param``: extract authentication parameter function pointer.
+
+The ``init()`` function will be used to initialize the IPL.
+
+The ``check_integrity()`` function is passed a pointer to the memory where the
+image has been loaded by the IO framework and the image length. It should ensure
+that the image is in the format corresponding to the parsing method and has not
+been tampered with. For example, RFC-2459 describes a validation sequence for an
+X.509 certificate.
+
+The ``get_auth_param()`` function is passed a parameter descriptor containing
+information about the parameter (``type_desc`` and ``cookie``) to identify and
+extract the data corresponding to that parameter from an image. This data will
+be used to verify either the current or the next image in the CoT sequence.
+
+Each image in the CoT will specify the parsing method it uses. This information
+will be used by the IPM to find the right parser descriptor for the image.
+
+Describing the authentication method(s)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As part of the CoT, each image has to specify one or more authentication methods
+which will be used to verify it. As described in the Section "Authentication
+methods", there are three methods supported by the AM.
+
+.. code:: c
+
+ typedef enum {
+ AUTH_METHOD_NONE,
+ AUTH_METHOD_HASH,
+ AUTH_METHOD_SIG,
+ AUTH_METHOD_NUM
+ } auth_method_type_t;
+
+The AM defines the type of each parameter used by an authentication method. It
+uses this information to:
+
+#. Specify to the ``get_auth_param()`` function exported by the IPM, which
+ parameter should be extracted from an image.
+
+#. Correctly marshall the parameters while calling the verification function
+ exported by the CM and PP.
+
+#. Extract authentication parameters from a parent image in order to verify a
+ child image e.g. to verify the certificate image, the public key has to be
+ obtained from the parent image.
+
+.. code:: c
+
+ typedef enum {
+ AUTH_PARAM_NONE,
+ AUTH_PARAM_RAW_DATA, /* Raw image data */
+ AUTH_PARAM_SIG, /* The image signature */
+ AUTH_PARAM_SIG_ALG, /* The image signature algorithm */
+ AUTH_PARAM_HASH, /* A hash (including the algorithm) */
+ AUTH_PARAM_PUB_KEY, /* A public key */
+ } auth_param_type_t;
+
+The AM defines the following structure to identify an authentication parameter
+required to verify an image.
+
+.. code:: c
+
+ typedef struct auth_param_type_desc_s {
+ auth_param_type_t type;
+ void *cookie;
+ } auth_param_type_desc_t;
+
+``cookie`` is used by the platform to specify additional information to the IPM
+which enables it to uniquely identify the parameter that should be extracted
+from an image. For example, the hash of a BL3x image in its corresponding
+content certificate is stored in an X509v3 custom extension field. An extension
+field can only be identified using an OID. In this case, the ``cookie`` could
+contain the pointer to the OID defined by the platform for the hash extension
+field while the ``type`` field could be set to ``AUTH_PARAM_HASH``. A value of 0 for
+the ``cookie`` field means that it is not used.
+
+For each method, the AM defines a structure with the parameters required to
+verify the image.
+
+.. code:: c
+
+ /*
+ * Parameters for authentication by hash matching
+ */
+ typedef struct auth_method_param_hash_s {
+ auth_param_type_desc_t *data; /* Data to hash */
+ auth_param_type_desc_t *hash; /* Hash to match with */
+ } auth_method_param_hash_t;
+
+ /*
+ * Parameters for authentication by signature
+ */
+ typedef struct auth_method_param_sig_s {
+ auth_param_type_desc_t *pk; /* Public key */
+ auth_param_type_desc_t *sig; /* Signature to check */
+ auth_param_type_desc_t *alg; /* Signature algorithm */
+ auth_param_type_desc_t *tbs; /* Data signed */
+ } auth_method_param_sig_t;
+
+The AM defines the following structure to describe an authentication method for
+verifying an image
+
+.. code:: c
+
+ /*
+ * Authentication method descriptor
+ */
+ typedef struct auth_method_desc_s {
+ auth_method_type_t type;
+ union {
+ auth_method_param_hash_t hash;
+ auth_method_param_sig_t sig;
+ } param;
+ } auth_method_desc_t;
+
+Using the method type specified in the ``type`` field, the AM finds out what field
+needs to access within the ``param`` union.
+
+Storing Authentication parameters
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A parameter described by ``auth_param_type_desc_t`` to verify an image could be
+obtained from either the image itself or its parent image. The memory allocated
+for loading the parent image will be reused for loading the child image. Hence
+parameters which are obtained from the parent for verifying a child image need
+to have memory allocated for them separately where they can be stored. This
+memory must be statically allocated by the platform port.
+
+The AM defines the following structure to store the data corresponding to an
+authentication parameter.
+
+.. code:: c
+
+ typedef struct auth_param_data_desc_s {
+ void *auth_param_ptr;
+ unsigned int auth_param_len;
+ } auth_param_data_desc_t;
+
+The ``auth_param_ptr`` field is initialized by the platform. The ``auth_param_len``
+field is used to specify the length of the data in the memory.
+
+For parameters that can be obtained from the child image itself, the IPM is
+responsible for populating the ``auth_param_ptr`` and ``auth_param_len`` fields
+while executing the ``img_get_auth_param()`` function.
+
+The AM defines the following structure to enable an image to describe the
+parameters that should be extracted from it and used to verify the next image
+(child) in a CoT.
+
+.. code:: c
+
+ typedef struct auth_param_desc_s {
+ auth_param_type_desc_t type_desc;
+ auth_param_data_desc_t data;
+ } auth_param_desc_t;
+
+Describing an image in a CoT
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An image in a CoT is a consolidation of the following aspects of a CoT described
+above.
+
+#. A unique identifier specified by the platform which allows the IO framework
+ to locate the image in a FIP and load it in the memory reserved for the data
+ image in the CoT.
+
+#. A parsing method which is used by the AM to find the appropriate IPM.
+
+#. Authentication methods and their parameters as described in the previous
+ section. These are used to verify the current image.
+
+#. Parameters which are used to verify the next image in the current CoT. These
+ parameters are specified only by authentication images and can be extracted
+ from the current image once it has been verified.
+
+The following data structure describes an image in a CoT.
+
+.. code:: c
+
+ typedef struct auth_img_desc_s {
+ unsigned int img_id;
+ const struct auth_img_desc_s *parent;
+ img_type_t img_type;
+ const auth_method_desc_t *const img_auth_methods;
+ const auth_param_desc_t *const authenticated_data;
+ } auth_img_desc_t;
+
+A CoT is defined as an array of pointers to ``auth_image_desc_t`` structures
+linked together by the ``parent`` field. Those nodes with no parent must be
+authenticated using the ROTPK stored in the platform.
+
+Implementation example
+----------------------
+
+This section is a detailed guide explaining a trusted boot implementation using
+the authentication framework. This example corresponds to the Applicative
+Functional Mode (AFM) as specified in the TBBR-Client document. It is
+recommended to read this guide along with the source code.
+
+The TBBR CoT
+~~~~~~~~~~~~
+
+The CoT can be found in ``drivers/auth/tbbr/tbbr_cot.c``. This CoT consists of
+an array of pointers to image descriptors and it is registered in the framework
+using the macro ``REGISTER_COT(cot_desc)``, where 'cot_desc' must be the name
+of the array (passing a pointer or any other type of indirection will cause the
+registration process to fail).
+
+The number of images participating in the boot process depends on the CoT.
+There is, however, a minimum set of images that are mandatory in TF-A and thus
+all CoTs must present:
+
+- ``BL2``
+- ``SCP_BL2`` (platform specific)
+- ``BL31``
+- ``BL32`` (optional)
+- ``BL33``
+
+The TBBR specifies the additional certificates that must accompany these images
+for a proper authentication. Details about the TBBR CoT may be found in the
+`Trusted Board Boot`_ document.
+
+Following the `Platform Porting Guide`_, a platform must provide unique
+identifiers for all the images and certificates that will be loaded during the
+boot process. If a platform is using the TBBR as a reference for trusted boot,
+these identifiers can be obtained from ``include/common/tbbr/tbbr_img_def.h``.
+Arm platforms include this file in ``include/plat/arm/common/arm_def.h``. Other
+platforms may also include this file or provide their own identifiers.
+
+**Important**: the authentication module uses these identifiers to index the
+CoT array, so the descriptors location in the array must match the identifiers.
+
+Each image descriptor must specify:
+
+- ``img_id``: the corresponding image unique identifier defined by the platform.
+- ``img_type``: the image parser module uses the image type to call the proper
+ parsing library to check the image integrity and extract the required
+ authentication parameters. Three types of images are currently supported:
+
+ - ``IMG_RAW``: image is a raw binary. No parsing functions are available,
+ other than reading the whole image.
+ - ``IMG_PLAT``: image format is platform specific. The platform may use this
+ type for custom images not directly supported by the authentication
+ framework.
+ - ``IMG_CERT``: image is an x509v3 certificate.
+
+- ``parent``: pointer to the parent image descriptor. The parent will contain
+ the information required to authenticate the current image. If the parent
+ is NULL, the authentication parameters will be obtained from the platform
+ (i.e. the BL2 and Trusted Key certificates are signed with the ROT private
+ key, whose public part is stored in the platform).
+- ``img_auth_methods``: this points to an array which defines the
+ authentication methods that must be checked to consider an image
+ authenticated. Each method consists of a type and a list of parameter
+ descriptors. A parameter descriptor consists of a type and a cookie which
+ will point to specific information required to extract that parameter from
+ the image (i.e. if the parameter is stored in an x509v3 extension, the
+ cookie will point to the extension OID). Depending on the method type, a
+ different number of parameters must be specified. This pointer should not be
+ NULL.
+ Supported methods are:
+
+ - ``AUTH_METHOD_HASH``: the hash of the image must match the hash extracted
+ from the parent image. The following parameter descriptors must be
+ specified:
+
+ - ``data``: data to be hashed (obtained from current image)
+ - ``hash``: reference hash (obtained from parent image)
+
+ - ``AUTH_METHOD_SIG``: the image (usually a certificate) must be signed with
+ the private key whose public part is extracted from the parent image (or
+ the platform if the parent is NULL). The following parameter descriptors
+ must be specified:
+
+ - ``pk``: the public key (obtained from parent image)
+ - ``sig``: the digital signature (obtained from current image)
+ - ``alg``: the signature algorithm used (obtained from current image)
+ - ``data``: the data to be signed (obtained from current image)
+
+- ``authenticated_data``: this array pointer indicates what authentication
+ parameters must be extracted from an image once it has been authenticated.
+ Each parameter consists of a parameter descriptor and the buffer
+ address/size to store the parameter. The CoT is responsible for allocating
+ the required memory to store the parameters. This pointer may be NULL.
+
+In the ``tbbr_cot.c`` file, a set of buffers are allocated to store the parameters
+extracted from the certificates. In the case of the TBBR CoT, these parameters
+are hashes and public keys. In DER format, an RSA-2048 public key requires 294
+bytes, and a hash requires 51 bytes. Depending on the CoT and the authentication
+process, some of the buffers may be reused at different stages during the boot.
+
+Next in that file, the parameter descriptors are defined. These descriptors will
+be used to extract the parameter data from the corresponding image.
+
+Example: the BL31 Chain of Trust
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Four image descriptors form the BL31 Chain of Trust:
+
+.. code:: c
+
+ static const auth_img_desc_t trusted_key_cert = {
+ .img_id = TRUSTED_KEY_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = NULL,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &subject_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &trusted_world_pk,
+ .data = {
+ .ptr = (void *)trusted_world_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &non_trusted_world_pk,
+ .data = {
+ .ptr = (void *)non_trusted_world_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ }
+ }
+ };
+ static const auth_img_desc_t soc_fw_key_cert = {
+ .img_id = SOC_FW_KEY_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &trusted_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &trusted_world_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &soc_fw_content_pk,
+ .data = {
+ .ptr = (void *)content_pk_buf,
+ .len = (unsigned int)PK_DER_LEN
+ }
+ }
+ }
+ };
+ static const auth_img_desc_t soc_fw_content_cert = {
+ .img_id = SOC_FW_CONTENT_CERT_ID,
+ .img_type = IMG_CERT,
+ .parent = &soc_fw_key_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_SIG,
+ .param.sig = {
+ .pk = &soc_fw_content_pk,
+ .sig = &sig,
+ .alg = &sig_alg,
+ .data = &raw_data
+ }
+ },
+ [1] = {
+ .type = AUTH_METHOD_NV_CTR,
+ .param.nv_ctr = {
+ .cert_nv_ctr = &trusted_nv_ctr,
+ .plat_nv_ctr = &trusted_nv_ctr
+ }
+ }
+ },
+ .authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
+ [0] = {
+ .type_desc = &soc_fw_hash,
+ .data = {
+ .ptr = (void *)soc_fw_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ },
+ [1] = {
+ .type_desc = &soc_fw_config_hash,
+ .data = {
+ .ptr = (void *)soc_fw_config_hash_buf,
+ .len = (unsigned int)HASH_DER_LEN
+ }
+ }
+ }
+ };
+ static const auth_img_desc_t bl31_image = {
+ .img_id = BL31_IMAGE_ID,
+ .img_type = IMG_RAW,
+ .parent = &soc_fw_content_cert,
+ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
+ [0] = {
+ .type = AUTH_METHOD_HASH,
+ .param.hash = {
+ .data = &raw_data,
+ .hash = &soc_fw_hash
+ }
+ }
+ }
+ };
+
+The **Trusted Key certificate** is signed with the ROT private key and contains
+the Trusted World public key and the Non-Trusted World public key as x509v3
+extensions. This must be specified in the image descriptor using the
+``img_auth_methods`` and ``authenticated_data`` arrays, respectively.
+
+The Trusted Key certificate is authenticated by checking its digital signature
+using the ROTPK. Four parameters are required to check a signature: the public
+key, the algorithm, the signature and the data that has been signed. Therefore,
+four parameter descriptors must be specified with the authentication method:
+
+- ``subject_pk``: parameter descriptor of type ``AUTH_PARAM_PUB_KEY``. This type
+ is used to extract a public key from the parent image. If the cookie is an
+ OID, the key is extracted from the corresponding x509v3 extension. If the
+ cookie is NULL, the subject public key is retrieved. In this case, because
+ the parent image is NULL, the public key is obtained from the platform
+ (this key will be the ROTPK).
+- ``sig``: parameter descriptor of type ``AUTH_PARAM_SIG``. It is used to extract
+ the signature from the certificate.
+- ``sig_alg``: parameter descriptor of type ``AUTH_PARAM_SIG``. It is used to
+ extract the signature algorithm from the certificate.
+- ``raw_data``: parameter descriptor of type ``AUTH_PARAM_RAW_DATA``. It is used
+ to extract the data to be signed from the certificate.
+
+Once the signature has been checked and the certificate authenticated, the
+Trusted World public key needs to be extracted from the certificate. A new entry
+is created in the ``authenticated_data`` array for that purpose. In that entry,
+the corresponding parameter descriptor must be specified along with the buffer
+address to store the parameter value. In this case, the ``tz_world_pk`` descriptor
+is used to extract the public key from an x509v3 extension with OID
+``TRUSTED_WORLD_PK_OID``. The BL31 key certificate will use this descriptor as
+parameter in the signature authentication method. The key is stored in the
+``plat_tz_world_pk_buf`` buffer.
+
+The **BL31 Key certificate** is authenticated by checking its digital signature
+using the Trusted World public key obtained previously from the Trusted Key
+certificate. In the image descriptor, we specify a single authentication method
+by signature whose public key is the ``tz_world_pk``. Once this certificate has
+been authenticated, we have to extract the BL31 public key, stored in the
+extension specified by ``bl31_content_pk``. This key will be copied to the
+``plat_content_pk`` buffer.
+
+The **BL31 certificate** is authenticated by checking its digital signature
+using the BL31 public key obtained previously from the BL31 Key certificate.
+We specify the authentication method using ``bl31_content_pk`` as public key.
+After authentication, we need to extract the BL31 hash, stored in the extension
+specified by ``bl31_hash``. This hash will be copied to the ``plat_bl31_hash_buf``
+buffer.
+
+The **BL31 image** is authenticated by calculating its hash and matching it
+with the hash obtained from the BL31 certificate. The image descriptor contains
+a single authentication method by hash. The parameters to the hash method are
+the reference hash, ``bl31_hash``, and the data to be hashed. In this case, it is
+the whole image, so we specify ``raw_data``.
+
+The image parser library
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The image parser module relies on libraries to check the image integrity and
+extract the authentication parameters. The number and type of parser libraries
+depend on the images used in the CoT. Raw images do not need a library, so
+only an x509v3 library is required for the TBBR CoT.
+
+Arm platforms will use an x509v3 library based on mbed TLS. This library may be
+found in ``drivers/auth/mbedtls/mbedtls_x509_parser.c``. It exports three
+functions:
+
+.. code:: c
+
+ void init(void);
+ int check_integrity(void *img, unsigned int img_len);
+ int get_auth_param(const auth_param_type_desc_t *type_desc,
+ void *img, unsigned int img_len,
+ void **param, unsigned int *param_len);
+
+The library is registered in the framework using the macro
+``REGISTER_IMG_PARSER_LIB()``. Each time the image parser module needs to access
+an image of type ``IMG_CERT``, it will call the corresponding function exported
+in this file.
+
+The build system must be updated to include the corresponding library and
+mbed TLS sources. Arm platforms use the ``arm_common.mk`` file to pull the
+sources.
+
+The cryptographic library
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The cryptographic module relies on a library to perform the required operations,
+i.e. verify a hash or a digital signature. Arm platforms will use a library
+based on mbed TLS, which can be found in
+``drivers/auth/mbedtls/mbedtls_crypto.c``. This library is registered in the
+authentication framework using the macro ``REGISTER_CRYPTO_LIB()`` and exports
+three functions:
+
+.. code:: c
+
+ void init(void);
+ int verify_signature(void *data_ptr, unsigned int data_len,
+ void *sig_ptr, unsigned int sig_len,
+ void *sig_alg, unsigned int sig_alg_len,
+ void *pk_ptr, unsigned int pk_len);
+ int verify_hash(void *data_ptr, unsigned int data_len,
+ void *digest_info_ptr, unsigned int digest_info_len);
+
+The mbedTLS library algorithm support is configured by the
+``TF_MBEDTLS_KEY_ALG`` variable which can take in 3 values: `rsa`, `ecdsa` or
+`rsa+ecdsa`. This variable allows the Makefile to include the corresponding
+sources in the build for the various algorithms. Setting the variable to
+`rsa+ecdsa` enables support for both rsa and ecdsa algorithms in the mbedTLS
+library.
+
+Note: If code size is a concern, the build option ``MBEDTLS_SHA256_SMALLER`` can
+be defined in the platform Makefile. It will make mbed TLS use an implementation
+of SHA-256 with smaller memory footprint (~1.5 KB less) but slower (~30%).
+
+--------------
+
+*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _Trusted Board Boot: ./trusted-board-boot.rst
+.. _Platform Porting Guide: ../getting_started/porting-guide.rst
+.. _TBBR-Client specification: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
--- /dev/null
+Arm CPU Specific Build Macros
+=============================
+
+
+
+
+.. contents::
+
+This document describes the various build options present in the CPU specific
+operations framework to enable errata workarounds and to enable optimizations
+for a specific CPU on a platform.
+
+Security Vulnerability Workarounds
+----------------------------------
+
+TF-A exports a series of build flags which control which security
+vulnerability workarounds should be applied at runtime.
+
+- ``WORKAROUND_CVE_2017_5715``: Enables the security workaround for
+ `CVE-2017-5715`_. This flag can be set to 0 by the platform if none
+ of the PEs in the system need the workaround. Setting this flag to 0 provides
+ no performance benefit for non-affected platforms, it just helps to comply
+ with the recommendation in the spec regarding workaround discovery.
+ Defaults to 1.
+
+- ``WORKAROUND_CVE_2018_3639``: Enables the security workaround for
+ `CVE-2018-3639`_. Defaults to 1. The TF-A project recommends to keep
+ the default value of 1 even on platforms that are unaffected by
+ CVE-2018-3639, in order to comply with the recommendation in the spec
+ regarding workaround discovery.
+
+- ``DYNAMIC_WORKAROUND_CVE_2018_3639``: Enables dynamic mitigation for
+ `CVE-2018-3639`_. This build option should be set to 1 if the target
+ platform contains at least 1 CPU that requires dynamic mitigation.
+ Defaults to 0.
+
+CPU Errata Workarounds
+----------------------
+
+TF-A exports a series of build flags which control the errata workarounds that
+are applied to each CPU by the reset handler. The errata details can be found
+in the CPU specific errata documents published by Arm:
+
+- `Cortex-A53 MPCore Software Developers Errata Notice`_
+- `Cortex-A57 MPCore Software Developers Errata Notice`_
+- `Cortex-A72 MPCore Software Developers Errata Notice`_
+
+The errata workarounds are implemented for a particular revision or a set of
+processor revisions. This is checked by the reset handler at runtime. Each
+errata workaround is identified by its ``ID`` as specified in the processor's
+errata notice document. The format of the define used to enable/disable the
+errata workaround is ``ERRATA_<Processor name>_<ID>``, where the ``Processor name``
+is for example ``A57`` for the ``Cortex_A57`` CPU.
+
+Refer to the section *CPU errata status reporting* in
+`Firmware Design guide`_ for information on how to write errata workaround
+functions.
+
+All workarounds are disabled by default. The platform is responsible for
+enabling these workarounds according to its requirement by defining the
+errata workaround build flags in the platform specific makefile. In case
+these workarounds are enabled for the wrong CPU revision then the errata
+workaround is not applied. In the DEBUG build, this is indicated by
+printing a warning to the crash console.
+
+In the current implementation, a platform which has more than 1 variant
+with different revisions of a processor has no runtime mechanism available
+for it to specify which errata workarounds should be enabled or not.
+
+The value of the build flags is 0 by default, that is, disabled. A value of 1
+will enable it.
+
+For Cortex-A9, the following errata build flags are defined :
+
+- ``ERRATA_A9_794073``: This applies errata 794073 workaround to Cortex-A9
+ CPU. This needs to be enabled for all revisions of the CPU.
+
+For Cortex-A15, the following errata build flags are defined :
+
+- ``ERRATA_A15_816470``: This applies errata 816470 workaround to Cortex-A15
+ CPU. This needs to be enabled only for revision >= r3p0 of the CPU.
+
+- ``ERRATA_A15_827671``: This applies errata 827671 workaround to Cortex-A15
+ CPU. This needs to be enabled only for revision >= r3p0 of the CPU.
+
+For Cortex-A17, the following errata build flags are defined :
+
+- ``ERRATA_A17_852421``: This applies errata 852421 workaround to Cortex-A17
+ CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
+
+- ``ERRATA_A17_852423``: This applies errata 852423 workaround to Cortex-A17
+ CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
+
+For Cortex-A35, the following errata build flags are defined :
+
+- ``ERRATA_A35_855472``: This applies errata 855472 workaround to Cortex-A35
+ CPUs. This needs to be enabled only for revision r0p0 of Cortex-A35.
+
+For Cortex-A53, the following errata build flags are defined :
+
+- ``ERRATA_A53_819472``: This applies errata 819472 workaround to all
+ CPUs. This needs to be enabled only for revision <= r0p1 of Cortex-A53.
+
+- ``ERRATA_A53_824069``: This applies errata 824069 workaround to all
+ CPUs. This needs to be enabled only for revision <= r0p2 of Cortex-A53.
+
+- ``ERRATA_A53_826319``: This applies errata 826319 workaround to Cortex-A53
+ CPU. This needs to be enabled only for revision <= r0p2 of the CPU.
+
+- ``ERRATA_A53_827319``: This applies errata 827319 workaround to all
+ CPUs. This needs to be enabled only for revision <= r0p2 of Cortex-A53.
+
+- ``ERRATA_A53_835769``: This applies erratum 835769 workaround at compile and
+ link time to Cortex-A53 CPU. This needs to be enabled for some variants of
+ revision <= r0p4. This workaround can lead the linker to create ``*.stub``
+ sections.
+
+- ``ERRATA_A53_836870``: This applies errata 836870 workaround to Cortex-A53
+ CPU. This needs to be enabled only for revision <= r0p3 of the CPU. From
+ r0p4 and onwards, this errata is enabled by default in hardware.
+
+- ``ERRATA_A53_843419``: This applies erratum 843419 workaround at link time
+ to Cortex-A53 CPU. This needs to be enabled for some variants of revision
+ <= r0p4. This workaround can lead the linker to emit ``*.stub`` sections
+ which are 4kB aligned.
+
+- ``ERRATA_A53_855873``: This applies errata 855873 workaround to Cortex-A53
+ CPUs. Though the erratum is present in every revision of the CPU,
+ this workaround is only applied to CPUs from r0p3 onwards, which feature
+ a chicken bit in CPUACTLR_EL1 to enable a hardware workaround.
+ Earlier revisions of the CPU have other errata which require the same
+ workaround in software, so they should be covered anyway.
+
+For Cortex-A55, the following errata build flags are defined :
+
+- ``ERRATA_A55_768277``: This applies errata 768277 workaround to Cortex-A55
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A55_778703``: This applies errata 778703 workaround to Cortex-A55
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A55_798797``: This applies errata 798797 workaround to Cortex-A55
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A55_846532``: This applies errata 846532 workaround to Cortex-A55
+ CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
+
+- ``ERRATA_A55_903758``: This applies errata 903758 workaround to Cortex-A55
+ CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
+
+For Cortex-A57, the following errata build flags are defined :
+
+- ``ERRATA_A57_806969``: This applies errata 806969 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A57_813419``: This applies errata 813419 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A57_813420``: This applies errata 813420 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A57_814670``: This applies errata 814670 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A57_817169``: This applies errata 817169 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
+
+- ``ERRATA_A57_826974``: This applies errata 826974 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
+
+- ``ERRATA_A57_826977``: This applies errata 826977 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
+
+- ``ERRATA_A57_828024``: This applies errata 828024 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
+
+- ``ERRATA_A57_829520``: This applies errata 829520 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
+
+- ``ERRATA_A57_833471``: This applies errata 833471 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p2 of the CPU.
+
+- ``ERRATA_A57_859972``: This applies errata 859972 workaround to Cortex-A57
+ CPU. This needs to be enabled only for revision <= r1p3 of the CPU.
+
+
+For Cortex-A72, the following errata build flags are defined :
+
+- ``ERRATA_A72_859971``: This applies errata 859971 workaround to Cortex-A72
+ CPU. This needs to be enabled only for revision <= r0p3 of the CPU.
+
+For Cortex-A73, the following errata build flags are defined :
+
+- ``ERRATA_A73_852427``: This applies errata 852427 workaround to Cortex-A73
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A73_855423``: This applies errata 855423 workaround to Cortex-A73
+ CPU. This needs to be enabled only for revision <= r0p1 of the CPU.
+
+For Cortex-A75, the following errata build flags are defined :
+
+- ``ERRATA_A75_764081``: This applies errata 764081 workaround to Cortex-A75
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+- ``ERRATA_A75_790748``: This applies errata 790748 workaround to Cortex-A75
+ CPU. This needs to be enabled only for revision r0p0 of the CPU.
+
+For Cortex-A76, the following errata build flags are defined :
+
+- ``ERRATA_A76_1073348``: This applies errata 1073348 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r1p0 of the CPU.
+
+- ``ERRATA_A76_1130799``: This applies errata 1130799 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r2p0 of the CPU.
+
+- ``ERRATA_A76_1220197``: This applies errata 1220197 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r2p0 of the CPU.
+
+- ``ERRATA_A76_1257314``: This applies errata 1257314 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
+
+- ``ERRATA_A76_1262606``: This applies errata 1262606 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
+
+- ``ERRATA_A76_1262888``: This applies errata 1262888 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
+
+- ``ERRATA_A76_1275112``: This applies errata 1275112 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
+
+DSU Errata Workarounds
+----------------------
+
+Similar to CPU errata, TF-A also implements workarounds for DSU (DynamIQ
+Shared Unit) errata. The DSU errata details can be found in the respective Arm
+documentation:
+
+- `Arm DSU Software Developers Errata Notice`_.
+
+Each erratum is identified by an ``ID``, as defined in the DSU errata notice
+document. Thus, the build flags which enable/disable the errata workarounds
+have the format ``ERRATA_DSU_<ID>``. The implementation and application logic
+of DSU errata workarounds are similar to `CPU errata workarounds`_.
+
+For DSU errata, the following build flags are defined:
+
+- ``ERRATA_DSU_798953``: This applies errata 798953 workaround for the
+ affected DSU configurations. This errata applies only for those DSUs that
+ revision is r0p0 (on r0p1 it is fixed). However, please note that this
+ workaround results in increased DSU power consumption on idle.
+
+- ``ERRATA_DSU_936184``: This applies errata 936184 workaround for the
+ affected DSU configurations. This errata applies only for those DSUs that
+ contain the ACP interface **and** the DSU revision is older than r2p0 (on
+ r2p0 it is fixed). However, please note that this workaround results in
+ increased DSU power consumption on idle.
+
+CPU Specific optimizations
+--------------------------
+
+This section describes some of the optimizations allowed by the CPU micro
+architecture that can be enabled by the platform as desired.
+
+- ``SKIP_A57_L1_FLUSH_PWR_DWN``: This flag enables an optimization in the
+ Cortex-A57 cluster power down sequence by not flushing the Level 1 data
+ cache. The L1 data cache and the L2 unified cache are inclusive. A flush
+ of the L2 by set/way flushes any dirty lines from the L1 as well. This
+ is a known safe deviation from the Cortex-A57 TRM defined power down
+ sequence. Each Cortex-A57 based platform must make its own decision on
+ whether to use the optimization.
+
+- ``A53_DISABLE_NON_TEMPORAL_HINT``: This flag disables the cache non-temporal
+ hint. The LDNP/STNP instructions as implemented on Cortex-A53 do not behave
+ in a way most programmers expect, and will most probably result in a
+ significant speed degradation to any code that employs them. The Armv8-A
+ architecture (see Arm DDI 0487A.h, section D3.4.3) allows cores to ignore
+ the non-temporal hint and treat LDNP/STNP as LDP/STP instead. Enabling this
+ flag enforces this behaviour. This needs to be enabled only for revisions
+ <= r0p3 of the CPU and is enabled by default.
+
+- ``A57_DISABLE_NON_TEMPORAL_HINT``: This flag has the same behaviour as
+ ``A53_DISABLE_NON_TEMPORAL_HINT`` but for Cortex-A57. This needs to be
+ enabled only for revisions <= r1p2 of the CPU and is enabled by default,
+ as recommended in section "4.7 Non-Temporal Loads/Stores" of the
+ `Cortex-A57 Software Optimization Guide`_.
+
+--------------
+
+*Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _CVE-2017-5715: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5715
+.. _CVE-2018-3639: http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-3639
+.. _Cortex-A53 MPCore Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm048406/index.html
+.. _Cortex-A57 MPCore Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm049219/index.html
+.. _Cortex-A72 MPCore Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm012079/index.html
+.. _Firmware Design guide: firmware-design.rst
+.. _Cortex-A57 Software Optimization Guide: http://infocenter.arm.com/help/topic/com.arm.doc.uan0015b/Cortex_A57_Software_Optimization_Guide_external.pdf
+.. _Arm DSU Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm138168/index.html
--- /dev/null
+Trusted Firmware-A design
+=========================
+
+
+
+
+.. contents::
+
+Trusted Firmware-A (TF-A) implements a subset of the Trusted Board Boot
+Requirements (TBBR) Platform Design Document (PDD) [1]_ for Arm reference
+platforms. The TBB sequence starts when the platform is powered on and runs up
+to the stage where it hands-off control to firmware running in the normal
+world in DRAM. This is the cold boot path.
+
+TF-A also implements the Power State Coordination Interface PDD [2]_ as a
+runtime service. PSCI is the interface from normal world software to firmware
+implementing power management use-cases (for example, secondary CPU boot,
+hotplug and idle). Normal world software can access TF-A runtime services via
+the Arm SMC (Secure Monitor Call) instruction. The SMC instruction must be
+used as mandated by the SMC Calling Convention [3]_.
+
+TF-A implements a framework for configuring and managing interrupts generated
+in either security state. The details of the interrupt management framework
+and its design can be found in TF-A Interrupt Management Design guide [4]_.
+
+TF-A also implements a library for setting up and managing the translation
+tables. The details of this library can be found in `Xlat_tables design`_.
+
+TF-A can be built to support either AArch64 or AArch32 execution state.
+
+Cold boot
+---------
+
+The cold boot path starts when the platform is physically turned on. If
+``COLD_BOOT_SINGLE_CPU=0``, one of the CPUs released from reset is chosen as the
+primary CPU, and the remaining CPUs are considered secondary CPUs. The primary
+CPU is chosen through platform-specific means. The cold boot path is mainly
+executed by the primary CPU, other than essential CPU initialization executed by
+all CPUs. The secondary CPUs are kept in a safe platform-specific state until
+the primary CPU has performed enough initialization to boot them.
+
+Refer to the `Reset Design`_ for more information on the effect of the
+``COLD_BOOT_SINGLE_CPU`` platform build option.
+
+The cold boot path in this implementation of TF-A depends on the execution
+state. For AArch64, it is divided into five steps (in order of execution):
+
+- Boot Loader stage 1 (BL1) *AP Trusted ROM*
+- Boot Loader stage 2 (BL2) *Trusted Boot Firmware*
+- Boot Loader stage 3-1 (BL31) *EL3 Runtime Software*
+- Boot Loader stage 3-2 (BL32) *Secure-EL1 Payload* (optional)
+- Boot Loader stage 3-3 (BL33) *Non-trusted Firmware*
+
+For AArch32, it is divided into four steps (in order of execution):
+
+- Boot Loader stage 1 (BL1) *AP Trusted ROM*
+- Boot Loader stage 2 (BL2) *Trusted Boot Firmware*
+- Boot Loader stage 3-2 (BL32) *EL3 Runtime Software*
+- Boot Loader stage 3-3 (BL33) *Non-trusted Firmware*
+
+Arm development platforms (Fixed Virtual Platforms (FVPs) and Juno) implement a
+combination of the following types of memory regions. Each bootloader stage uses
+one or more of these memory regions.
+
+- Regions accessible from both non-secure and secure states. For example,
+ non-trusted SRAM, ROM and DRAM.
+- Regions accessible from only the secure state. For example, trusted SRAM and
+ ROM. The FVPs also implement the trusted DRAM which is statically
+ configured. Additionally, the Base FVPs and Juno development platform
+ configure the TrustZone Controller (TZC) to create a region in the DRAM
+ which is accessible only from the secure state.
+
+The sections below provide the following details:
+
+- dynamic configuration of Boot Loader stages
+- initialization and execution of the first three stages during cold boot
+- specification of the EL3 Runtime Software (BL31 for AArch64 and BL32 for
+ AArch32) entrypoint requirements for use by alternative Trusted Boot
+ Firmware in place of the provided BL1 and BL2
+
+Dynamic Configuration during cold boot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each of the Boot Loader stages may be dynamically configured if required by the
+platform. The Boot Loader stage may optionally specify a firmware
+configuration file and/or hardware configuration file as listed below:
+
+- HW_CONFIG - The hardware configuration file. Can be shared by all Boot Loader
+ stages and also by the Normal World Rich OS.
+- TB_FW_CONFIG - Trusted Boot Firmware configuration file. Shared between BL1
+ and BL2.
+- SOC_FW_CONFIG - SoC Firmware configuration file. Used by BL31.
+- TOS_FW_CONFIG - Trusted OS Firmware configuration file. Used by Trusted OS
+ (BL32).
+- NT_FW_CONFIG - Non Trusted Firmware configuration file. Used by Non-trusted
+ firmware (BL33).
+
+The Arm development platforms use the Flattened Device Tree format for the
+dynamic configuration files.
+
+Each Boot Loader stage can pass up to 4 arguments via registers to the next
+stage. BL2 passes the list of the next images to execute to the *EL3 Runtime
+Software* (BL31 for AArch64 and BL32 for AArch32) via `arg0`. All the other
+arguments are platform defined. The Arm development platforms use the following
+convention:
+
+- BL1 passes the address of a meminfo_t structure to BL2 via ``arg1``. This
+ structure contains the memory layout available to BL2.
+- When dynamic configuration files are present, the firmware configuration for
+ the next Boot Loader stage is populated in the first available argument and
+ the generic hardware configuration is passed the next available argument.
+ For example,
+
+ - If TB_FW_CONFIG is loaded by BL1, then its address is passed in ``arg0``
+ to BL2.
+ - If HW_CONFIG is loaded by BL1, then its address is passed in ``arg2`` to
+ BL2. Note, ``arg1`` is already used for meminfo_t.
+ - If SOC_FW_CONFIG is loaded by BL2, then its address is passed in ``arg1``
+ to BL31. Note, ``arg0`` is used to pass the list of executable images.
+ - Similarly, if HW_CONFIG is loaded by BL1 or BL2, then its address is
+ passed in ``arg2`` to BL31.
+ - For other BL3x images, if the firmware configuration file is loaded by
+ BL2, then its address is passed in ``arg0`` and if HW_CONFIG is loaded
+ then its address is passed in ``arg1``.
+
+BL1
+~~~
+
+This stage begins execution from the platform's reset vector at EL3. The reset
+address is platform dependent but it is usually located in a Trusted ROM area.
+The BL1 data section is copied to trusted SRAM at runtime.
+
+On the Arm development platforms, BL1 code starts execution from the reset
+vector defined by the constant ``BL1_RO_BASE``. The BL1 data section is copied
+to the top of trusted SRAM as defined by the constant ``BL1_RW_BASE``.
+
+The functionality implemented by this stage is as follows.
+
+Determination of boot path
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Whenever a CPU is released from reset, BL1 needs to distinguish between a warm
+boot and a cold boot. This is done using platform-specific mechanisms (see the
+``plat_get_my_entrypoint()`` function in the `Porting Guide`_). In the case of a
+warm boot, a CPU is expected to continue execution from a separate
+entrypoint. In the case of a cold boot, the secondary CPUs are placed in a safe
+platform-specific state (see the ``plat_secondary_cold_boot_setup()`` function in
+the `Porting Guide`_) while the primary CPU executes the remaining cold boot path
+as described in the following sections.
+
+This step only applies when ``PROGRAMMABLE_RESET_ADDRESS=0``. Refer to the
+`Reset Design`_ for more information on the effect of the
+``PROGRAMMABLE_RESET_ADDRESS`` platform build option.
+
+Architectural initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+BL1 performs minimal architectural initialization as follows.
+
+- Exception vectors
+
+ BL1 sets up simple exception vectors for both synchronous and asynchronous
+ exceptions. The default behavior upon receiving an exception is to populate
+ a status code in the general purpose register ``X0/R0`` and call the
+ ``plat_report_exception()`` function (see the `Porting Guide`_). The status
+ code is one of:
+
+ For AArch64:
+
+ ::
+
+ 0x0 : Synchronous exception from Current EL with SP_EL0
+ 0x1 : IRQ exception from Current EL with SP_EL0
+ 0x2 : FIQ exception from Current EL with SP_EL0
+ 0x3 : System Error exception from Current EL with SP_EL0
+ 0x4 : Synchronous exception from Current EL with SP_ELx
+ 0x5 : IRQ exception from Current EL with SP_ELx
+ 0x6 : FIQ exception from Current EL with SP_ELx
+ 0x7 : System Error exception from Current EL with SP_ELx
+ 0x8 : Synchronous exception from Lower EL using aarch64
+ 0x9 : IRQ exception from Lower EL using aarch64
+ 0xa : FIQ exception from Lower EL using aarch64
+ 0xb : System Error exception from Lower EL using aarch64
+ 0xc : Synchronous exception from Lower EL using aarch32
+ 0xd : IRQ exception from Lower EL using aarch32
+ 0xe : FIQ exception from Lower EL using aarch32
+ 0xf : System Error exception from Lower EL using aarch32
+
+ For AArch32:
+
+ ::
+
+ 0x10 : User mode
+ 0x11 : FIQ mode
+ 0x12 : IRQ mode
+ 0x13 : SVC mode
+ 0x16 : Monitor mode
+ 0x17 : Abort mode
+ 0x1a : Hypervisor mode
+ 0x1b : Undefined mode
+ 0x1f : System mode
+
+ The ``plat_report_exception()`` implementation on the Arm FVP port programs
+ the Versatile Express System LED register in the following format to
+ indicate the occurrence of an unexpected exception:
+
+ ::
+
+ SYS_LED[0] - Security state (Secure=0/Non-Secure=1)
+ SYS_LED[2:1] - Exception Level (EL3=0x3, EL2=0x2, EL1=0x1, EL0=0x0)
+ For AArch32 it is always 0x0
+ SYS_LED[7:3] - Exception Class (Sync/Async & origin). This is the value
+ of the status code
+
+ A write to the LED register reflects in the System LEDs (S6LED0..7) in the
+ CLCD window of the FVP.
+
+ BL1 does not expect to receive any exceptions other than the SMC exception.
+ For the latter, BL1 installs a simple stub. The stub expects to receive a
+ limited set of SMC types (determined by their function IDs in the general
+ purpose register ``X0/R0``):
+
+ - ``BL1_SMC_RUN_IMAGE``: This SMC is raised by BL2 to make BL1 pass control
+ to EL3 Runtime Software.
+ - All SMCs listed in section "BL1 SMC Interface" in the `Firmware Update`_
+ Design Guide are supported for AArch64 only. These SMCs are currently
+ not supported when BL1 is built for AArch32.
+
+ Any other SMC leads to an assertion failure.
+
+- CPU initialization
+
+ BL1 calls the ``reset_handler()`` function which in turn calls the CPU
+ specific reset handler function (see the section: "CPU specific operations
+ framework").
+
+- Control register setup (for AArch64)
+
+ - ``SCTLR_EL3``. Instruction cache is enabled by setting the ``SCTLR_EL3.I``
+ bit. Alignment and stack alignment checking is enabled by setting the
+ ``SCTLR_EL3.A`` and ``SCTLR_EL3.SA`` bits. Exception endianness is set to
+ little-endian by clearing the ``SCTLR_EL3.EE`` bit.
+
+ - ``SCR_EL3``. The register width of the next lower exception level is set
+ to AArch64 by setting the ``SCR.RW`` bit. The ``SCR.EA`` bit is set to trap
+ both External Aborts and SError Interrupts in EL3. The ``SCR.SIF`` bit is
+ also set to disable instruction fetches from Non-secure memory when in
+ secure state.
+
+ - ``CPTR_EL3``. Accesses to the ``CPACR_EL1`` register from EL1 or EL2, or the
+ ``CPTR_EL2`` register from EL2 are configured to not trap to EL3 by
+ clearing the ``CPTR_EL3.TCPAC`` bit. Access to the trace functionality is
+ configured not to trap to EL3 by clearing the ``CPTR_EL3.TTA`` bit.
+ Instructions that access the registers associated with Floating Point
+ and Advanced SIMD execution are configured to not trap to EL3 by
+ clearing the ``CPTR_EL3.TFP`` bit.
+
+ - ``DAIF``. The SError interrupt is enabled by clearing the SError interrupt
+ mask bit.
+
+ - ``MDCR_EL3``. The trap controls, ``MDCR_EL3.TDOSA``, ``MDCR_EL3.TDA`` and
+ ``MDCR_EL3.TPM``, are set so that accesses to the registers they control
+ do not trap to EL3. AArch64 Secure self-hosted debug is disabled by
+ setting the ``MDCR_EL3.SDD`` bit. Also ``MDCR_EL3.SPD32`` is set to
+ disable AArch32 Secure self-hosted privileged debug from S-EL1.
+
+- Control register setup (for AArch32)
+
+ - ``SCTLR``. Instruction cache is enabled by setting the ``SCTLR.I`` bit.
+ Alignment checking is enabled by setting the ``SCTLR.A`` bit.
+ Exception endianness is set to little-endian by clearing the
+ ``SCTLR.EE`` bit.
+
+ - ``SCR``. The ``SCR.SIF`` bit is set to disable instruction fetches from
+ Non-secure memory when in secure state.
+
+ - ``CPACR``. Allow execution of Advanced SIMD instructions at PL0 and PL1,
+ by clearing the ``CPACR.ASEDIS`` bit. Access to the trace functionality
+ is configured not to trap to undefined mode by clearing the
+ ``CPACR.TRCDIS`` bit.
+
+ - ``NSACR``. Enable non-secure access to Advanced SIMD functionality and
+ system register access to implemented trace registers.
+
+ - ``FPEXC``. Enable access to the Advanced SIMD and floating-point
+ functionality from all Exception levels.
+
+ - ``CPSR.A``. The Asynchronous data abort interrupt is enabled by clearing
+ the Asynchronous data abort interrupt mask bit.
+
+ - ``SDCR``. The ``SDCR.SPD`` field is set to disable AArch32 Secure
+ self-hosted privileged debug.
+
+Platform initialization
+^^^^^^^^^^^^^^^^^^^^^^^
+
+On Arm platforms, BL1 performs the following platform initializations:
+
+- Enable the Trusted Watchdog.
+- Initialize the console.
+- Configure the Interconnect to enable hardware coherency.
+- Enable the MMU and map the memory it needs to access.
+- Configure any required platform storage to load the next bootloader image
+ (BL2).
+- If the BL1 dynamic configuration file, ``TB_FW_CONFIG``, is available, then
+ load it to the platform defined address and make it available to BL2 via
+ ``arg0``.
+- Configure the system timer and program the `CNTFRQ_EL0` for use by NS-BL1U
+ and NS-BL2U firmware update images.
+
+Firmware Update detection and execution
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+After performing platform setup, BL1 common code calls
+``bl1_plat_get_next_image_id()`` to determine if `Firmware Update`_ is required or
+to proceed with the normal boot process. If the platform code returns
+``BL2_IMAGE_ID`` then the normal boot sequence is executed as described in the
+next section, else BL1 assumes that `Firmware Update`_ is required and execution
+passes to the first image in the `Firmware Update`_ process. In either case, BL1
+retrieves a descriptor of the next image by calling ``bl1_plat_get_image_desc()``.
+The image descriptor contains an ``entry_point_info_t`` structure, which BL1
+uses to initialize the execution state of the next image.
+
+BL2 image load and execution
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the normal boot flow, BL1 execution continues as follows:
+
+#. BL1 prints the following string from the primary CPU to indicate successful
+ execution of the BL1 stage:
+
+ ::
+
+ "Booting Trusted Firmware"
+
+#. BL1 loads a BL2 raw binary image from platform storage, at a
+ platform-specific base address. Prior to the load, BL1 invokes
+ ``bl1_plat_handle_pre_image_load()`` which allows the platform to update or
+ use the image information. If the BL2 image file is not present or if
+ there is not enough free trusted SRAM the following error message is
+ printed:
+
+ ::
+
+ "Failed to load BL2 firmware."
+
+#. BL1 invokes ``bl1_plat_handle_post_image_load()`` which again is intended
+ for platforms to take further action after image load. This function must
+ populate the necessary arguments for BL2, which may also include the memory
+ layout. Further description of the memory layout can be found later
+ in this document.
+
+#. BL1 passes control to the BL2 image at Secure EL1 (for AArch64) or at
+ Secure SVC mode (for AArch32), starting from its load address.
+
+BL2
+~~~
+
+BL1 loads and passes control to BL2 at Secure-EL1 (for AArch64) or at Secure
+SVC mode (for AArch32) . BL2 is linked against and loaded at a platform-specific
+base address (more information can be found later in this document).
+The functionality implemented by BL2 is as follows.
+
+Architectural initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For AArch64, BL2 performs the minimal architectural initialization required
+for subsequent stages of TF-A and normal world software. EL1 and EL0 are given
+access to Floating Point and Advanced SIMD registers by clearing the
+``CPACR.FPEN`` bits.
+
+For AArch32, the minimal architectural initialization required for subsequent
+stages of TF-A and normal world software is taken care of in BL1 as both BL1
+and BL2 execute at PL1.
+
+Platform initialization
+^^^^^^^^^^^^^^^^^^^^^^^
+
+On Arm platforms, BL2 performs the following platform initializations:
+
+- Initialize the console.
+- Configure any required platform storage to allow loading further bootloader
+ images.
+- Enable the MMU and map the memory it needs to access.
+- Perform platform security setup to allow access to controlled components.
+- Reserve some memory for passing information to the next bootloader image
+ EL3 Runtime Software and populate it.
+- Define the extents of memory available for loading each subsequent
+ bootloader image.
+- If BL1 has passed TB_FW_CONFIG dynamic configuration file in ``arg0``,
+ then parse it.
+
+Image loading in BL2
+^^^^^^^^^^^^^^^^^^^^
+
+BL2 generic code loads the images based on the list of loadable images
+provided by the platform. BL2 passes the list of executable images
+provided by the platform to the next handover BL image.
+
+The list of loadable images provided by the platform may also contain
+dynamic configuration files. The files are loaded and can be parsed as
+needed in the ``bl2_plat_handle_post_image_load()`` function. These
+configuration files can be passed to next Boot Loader stages as arguments
+by updating the corresponding entrypoint information in this function.
+
+SCP_BL2 (System Control Processor Firmware) image load
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Some systems have a separate System Control Processor (SCP) for power, clock,
+reset and system control. BL2 loads the optional SCP_BL2 image from platform
+storage into a platform-specific region of secure memory. The subsequent
+handling of SCP_BL2 is platform specific. For example, on the Juno Arm
+development platform port the image is transferred into SCP's internal memory
+using the Boot Over MHU (BOM) protocol after being loaded in the trusted SRAM
+memory. The SCP executes SCP_BL2 and signals to the Application Processor (AP)
+for BL2 execution to continue.
+
+EL3 Runtime Software image load
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+BL2 loads the EL3 Runtime Software image from platform storage into a platform-
+specific address in trusted SRAM. If there is not enough memory to load the
+image or image is missing it leads to an assertion failure.
+
+AArch64 BL32 (Secure-EL1 Payload) image load
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+BL2 loads the optional BL32 image from platform storage into a platform-
+specific region of secure memory. The image executes in the secure world. BL2
+relies on BL31 to pass control to the BL32 image, if present. Hence, BL2
+populates a platform-specific area of memory with the entrypoint/load-address
+of the BL32 image. The value of the Saved Processor Status Register (``SPSR``)
+for entry into BL32 is not determined by BL2, it is initialized by the
+Secure-EL1 Payload Dispatcher (see later) within BL31, which is responsible for
+managing interaction with BL32. This information is passed to BL31.
+
+BL33 (Non-trusted Firmware) image load
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+BL2 loads the BL33 image (e.g. UEFI or other test or boot software) from
+platform storage into non-secure memory as defined by the platform.
+
+BL2 relies on EL3 Runtime Software to pass control to BL33 once secure state
+initialization is complete. Hence, BL2 populates a platform-specific area of
+memory with the entrypoint and Saved Program Status Register (``SPSR``) of the
+normal world software image. The entrypoint is the load address of the BL33
+image. The ``SPSR`` is determined as specified in Section 5.13 of the
+`PSCI PDD`_. This information is passed to the EL3 Runtime Software.
+
+AArch64 BL31 (EL3 Runtime Software) execution
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+BL2 execution continues as follows:
+
+#. BL2 passes control back to BL1 by raising an SMC, providing BL1 with the
+ BL31 entrypoint. The exception is handled by the SMC exception handler
+ installed by BL1.
+
+#. BL1 turns off the MMU and flushes the caches. It clears the
+ ``SCTLR_EL3.M/I/C`` bits, flushes the data cache to the point of coherency
+ and invalidates the TLBs.
+
+#. BL1 passes control to BL31 at the specified entrypoint at EL3.
+
+Running BL2 at EL3 execution level
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some platforms have a non-TF-A Boot ROM that expects the next boot stage
+to execute at EL3. On these platforms, TF-A BL1 is a waste of memory
+as its only purpose is to ensure TF-A BL2 is entered at S-EL1. To avoid
+this waste, a special mode enables BL2 to execute at EL3, which allows
+a non-TF-A Boot ROM to load and jump directly to BL2. This mode is selected
+when the build flag BL2_AT_EL3 is enabled. The main differences in this
+mode are:
+
+#. BL2 includes the reset code and the mailbox mechanism to differentiate
+ cold boot and warm boot. It runs at EL3 doing the arch
+ initialization required for EL3.
+
+#. BL2 does not receive the meminfo information from BL1 anymore. This
+ information can be passed by the Boot ROM or be internal to the
+ BL2 image.
+
+#. Since BL2 executes at EL3, BL2 jumps directly to the next image,
+ instead of invoking the RUN_IMAGE SMC call.
+
+
+We assume 3 different types of BootROM support on the platform:
+
+#. The Boot ROM always jumps to the same address, for both cold
+ and warm boot. In this case, we will need to keep a resident part
+ of BL2 whose memory cannot be reclaimed by any other image. The
+ linker script defines the symbols __TEXT_RESIDENT_START__ and
+ __TEXT_RESIDENT_END__ that allows the platform to configure
+ correctly the memory map.
+#. The platform has some mechanism to indicate the jump address to the
+ Boot ROM. Platform code can then program the jump address with
+ psci_warmboot_entrypoint during cold boot.
+#. The platform has some mechanism to program the reset address using
+ the PROGRAMMABLE_RESET_ADDRESS feature. Platform code can then
+ program the reset address with psci_warmboot_entrypoint during
+ cold boot, bypassing the boot ROM for warm boot.
+
+In the last 2 cases, no part of BL2 needs to remain resident at
+runtime. In the first 2 cases, we expect the Boot ROM to be able to
+differentiate between warm and cold boot, to avoid loading BL2 again
+during warm boot.
+
+This functionality can be tested with FVP loading the image directly
+in memory and changing the address where the system jumps at reset.
+For example:
+
+ -C cluster0.cpu0.RVBAR=0x4022000
+ --data cluster0.cpu0=bl2.bin@0x4022000
+
+With this configuration, FVP is like a platform of the first case,
+where the Boot ROM jumps always to the same address. For simplification,
+BL32 is loaded in DRAM in this case, to avoid other images reclaiming
+BL2 memory.
+
+
+AArch64 BL31
+~~~~~~~~~~~~
+
+The image for this stage is loaded by BL2 and BL1 passes control to BL31 at
+EL3. BL31 executes solely in trusted SRAM. BL31 is linked against and
+loaded at a platform-specific base address (more information can be found later
+in this document). The functionality implemented by BL31 is as follows.
+
+Architectural initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Currently, BL31 performs a similar architectural initialization to BL1 as
+far as system register settings are concerned. Since BL1 code resides in ROM,
+architectural initialization in BL31 allows override of any previous
+initialization done by BL1.
+
+BL31 initializes the per-CPU data framework, which provides a cache of
+frequently accessed per-CPU data optimised for fast, concurrent manipulation
+on different CPUs. This buffer includes pointers to per-CPU contexts, crash
+buffer, CPU reset and power down operations, PSCI data, platform data and so on.
+
+It then replaces the exception vectors populated by BL1 with its own. BL31
+exception vectors implement more elaborate support for handling SMCs since this
+is the only mechanism to access the runtime services implemented by BL31 (PSCI
+for example). BL31 checks each SMC for validity as specified by the
+`SMC calling convention PDD`_ before passing control to the required SMC
+handler routine.
+
+BL31 programs the ``CNTFRQ_EL0`` register with the clock frequency of the system
+counter, which is provided by the platform.
+
+Platform initialization
+^^^^^^^^^^^^^^^^^^^^^^^
+
+BL31 performs detailed platform initialization, which enables normal world
+software to function correctly.
+
+On Arm platforms, this consists of the following:
+
+- Initialize the console.
+- Configure the Interconnect to enable hardware coherency.
+- Enable the MMU and map the memory it needs to access.
+- Initialize the generic interrupt controller.
+- Initialize the power controller device.
+- Detect the system topology.
+
+Runtime services initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+BL31 is responsible for initializing the runtime services. One of them is PSCI.
+
+As part of the PSCI initializations, BL31 detects the system topology. It also
+initializes the data structures that implement the state machine used to track
+the state of power domain nodes. The state can be one of ``OFF``, ``RUN`` or
+``RETENTION``. All secondary CPUs are initially in the ``OFF`` state. The cluster
+that the primary CPU belongs to is ``ON``; any other cluster is ``OFF``. It also
+initializes the locks that protect them. BL31 accesses the state of a CPU or
+cluster immediately after reset and before the data cache is enabled in the
+warm boot path. It is not currently possible to use 'exclusive' based spinlocks,
+therefore BL31 uses locks based on Lamport's Bakery algorithm instead.
+
+The runtime service framework and its initialization is described in more
+detail in the "EL3 runtime services framework" section below.
+
+Details about the status of the PSCI implementation are provided in the
+"Power State Coordination Interface" section below.
+
+AArch64 BL32 (Secure-EL1 Payload) image initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If a BL32 image is present then there must be a matching Secure-EL1 Payload
+Dispatcher (SPD) service (see later for details). During initialization
+that service must register a function to carry out initialization of BL32
+once the runtime services are fully initialized. BL31 invokes such a
+registered function to initialize BL32 before running BL33. This initialization
+is not necessary for AArch32 SPs.
+
+Details on BL32 initialization and the SPD's role are described in the
+"Secure-EL1 Payloads and Dispatchers" section below.
+
+BL33 (Non-trusted Firmware) execution
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+EL3 Runtime Software initializes the EL2 or EL1 processor context for normal-
+world cold boot, ensuring that no secure state information finds its way into
+the non-secure execution state. EL3 Runtime Software uses the entrypoint
+information provided by BL2 to jump to the Non-trusted firmware image (BL33)
+at the highest available Exception Level (EL2 if available, otherwise EL1).
+
+Using alternative Trusted Boot Firmware in place of BL1 & BL2 (AArch64 only)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some platforms have existing implementations of Trusted Boot Firmware that
+would like to use TF-A BL31 for the EL3 Runtime Software. To enable this
+firmware architecture it is important to provide a fully documented and stable
+interface between the Trusted Boot Firmware and BL31.
+
+Future changes to the BL31 interface will be done in a backwards compatible
+way, and this enables these firmware components to be independently enhanced/
+updated to develop and exploit new functionality.
+
+Required CPU state when calling ``bl31_entrypoint()`` during cold boot
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function must only be called by the primary CPU.
+
+On entry to this function the calling primary CPU must be executing in AArch64
+EL3, little-endian data access, and all interrupt sources masked:
+
+::
+
+ PSTATE.EL = 3
+ PSTATE.RW = 1
+ PSTATE.DAIF = 0xf
+ SCTLR_EL3.EE = 0
+
+X0 and X1 can be used to pass information from the Trusted Boot Firmware to the
+platform code in BL31:
+
+::
+
+ X0 : Reserved for common TF-A information
+ X1 : Platform specific information
+
+BL31 zero-init sections (e.g. ``.bss``) should not contain valid data on entry,
+these will be zero filled prior to invoking platform setup code.
+
+Use of the X0 and X1 parameters
+'''''''''''''''''''''''''''''''
+
+The parameters are platform specific and passed from ``bl31_entrypoint()`` to
+``bl31_early_platform_setup()``. The value of these parameters is never directly
+used by the common BL31 code.
+
+The convention is that ``X0`` conveys information regarding the BL31, BL32 and
+BL33 images from the Trusted Boot firmware and ``X1`` can be used for other
+platform specific purpose. This convention allows platforms which use TF-A's
+BL1 and BL2 images to transfer additional platform specific information from
+Secure Boot without conflicting with future evolution of TF-A using ``X0`` to
+pass a ``bl31_params`` structure.
+
+BL31 common and SPD initialization code depends on image and entrypoint
+information about BL33 and BL32, which is provided via BL31 platform APIs.
+This information is required until the start of execution of BL33. This
+information can be provided in a platform defined manner, e.g. compiled into
+the platform code in BL31, or provided in a platform defined memory location
+by the Trusted Boot firmware, or passed from the Trusted Boot Firmware via the
+Cold boot Initialization parameters. This data may need to be cleaned out of
+the CPU caches if it is provided by an earlier boot stage and then accessed by
+BL31 platform code before the caches are enabled.
+
+TF-A's BL2 implementation passes a ``bl31_params`` structure in
+``X0`` and the Arm development platforms interpret this in the BL31 platform
+code.
+
+MMU, Data caches & Coherency
+''''''''''''''''''''''''''''
+
+BL31 does not depend on the enabled state of the MMU, data caches or
+interconnect coherency on entry to ``bl31_entrypoint()``. If these are disabled
+on entry, these should be enabled during ``bl31_plat_arch_setup()``.
+
+Data structures used in the BL31 cold boot interface
+''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+These structures are designed to support compatibility and independent
+evolution of the structures and the firmware images. For example, a version of
+BL31 that can interpret the BL3x image information from different versions of
+BL2, a platform that uses an extended entry_point_info structure to convey
+additional register information to BL31, or a ELF image loader that can convey
+more details about the firmware images.
+
+To support these scenarios the structures are versioned and sized, which enables
+BL31 to detect which information is present and respond appropriately. The
+``param_header`` is defined to capture this information:
+
+.. code:: c
+
+ typedef struct param_header {
+ uint8_t type; /* type of the structure */
+ uint8_t version; /* version of this structure */
+ uint16_t size; /* size of this structure in bytes */
+ uint32_t attr; /* attributes: unused bits SBZ */
+ } param_header_t;
+
+The structures using this format are ``entry_point_info``, ``image_info`` and
+``bl31_params``. The code that allocates and populates these structures must set
+the header fields appropriately, and the ``SET_PARAM_HEAD()`` a macro is defined
+to simplify this action.
+
+Required CPU state for BL31 Warm boot initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When requesting a CPU power-on, or suspending a running CPU, TF-A provides
+the platform power management code with a Warm boot initialization
+entry-point, to be invoked by the CPU immediately after the reset handler.
+On entry to the Warm boot initialization function the calling CPU must be in
+AArch64 EL3, little-endian data access and all interrupt sources masked:
+
+::
+
+ PSTATE.EL = 3
+ PSTATE.RW = 1
+ PSTATE.DAIF = 0xf
+ SCTLR_EL3.EE = 0
+
+The PSCI implementation will initialize the processor state and ensure that the
+platform power management code is then invoked as required to initialize all
+necessary system, cluster and CPU resources.
+
+AArch32 EL3 Runtime Software entrypoint interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To enable this firmware architecture it is important to provide a fully
+documented and stable interface between the Trusted Boot Firmware and the
+AArch32 EL3 Runtime Software.
+
+Future changes to the entrypoint interface will be done in a backwards
+compatible way, and this enables these firmware components to be independently
+enhanced/updated to develop and exploit new functionality.
+
+Required CPU state when entering during cold boot
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This function must only be called by the primary CPU.
+
+On entry to this function the calling primary CPU must be executing in AArch32
+EL3, little-endian data access, and all interrupt sources masked:
+
+::
+
+ PSTATE.AIF = 0x7
+ SCTLR.EE = 0
+
+R0 and R1 are used to pass information from the Trusted Boot Firmware to the
+platform code in AArch32 EL3 Runtime Software:
+
+::
+
+ R0 : Reserved for common TF-A information
+ R1 : Platform specific information
+
+Use of the R0 and R1 parameters
+'''''''''''''''''''''''''''''''
+
+The parameters are platform specific and the convention is that ``R0`` conveys
+information regarding the BL3x images from the Trusted Boot firmware and ``R1``
+can be used for other platform specific purpose. This convention allows
+platforms which use TF-A's BL1 and BL2 images to transfer additional platform
+specific information from Secure Boot without conflicting with future
+evolution of TF-A using ``R0`` to pass a ``bl_params`` structure.
+
+The AArch32 EL3 Runtime Software is responsible for entry into BL33. This
+information can be obtained in a platform defined manner, e.g. compiled into
+the AArch32 EL3 Runtime Software, or provided in a platform defined memory
+location by the Trusted Boot firmware, or passed from the Trusted Boot Firmware
+via the Cold boot Initialization parameters. This data may need to be cleaned
+out of the CPU caches if it is provided by an earlier boot stage and then
+accessed by AArch32 EL3 Runtime Software before the caches are enabled.
+
+When using AArch32 EL3 Runtime Software, the Arm development platforms pass a
+``bl_params`` structure in ``R0`` from BL2 to be interpreted by AArch32 EL3 Runtime
+Software platform code.
+
+MMU, Data caches & Coherency
+''''''''''''''''''''''''''''
+
+AArch32 EL3 Runtime Software must not depend on the enabled state of the MMU,
+data caches or interconnect coherency in its entrypoint. They must be explicitly
+enabled if required.
+
+Data structures used in cold boot interface
+'''''''''''''''''''''''''''''''''''''''''''
+
+The AArch32 EL3 Runtime Software cold boot interface uses ``bl_params`` instead
+of ``bl31_params``. The ``bl_params`` structure is based on the convention
+described in AArch64 BL31 cold boot interface section.
+
+Required CPU state for warm boot initialization
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When requesting a CPU power-on, or suspending a running CPU, AArch32 EL3
+Runtime Software must ensure execution of a warm boot initialization entrypoint.
+If TF-A BL1 is used and the PROGRAMMABLE_RESET_ADDRESS build flag is false,
+then AArch32 EL3 Runtime Software must ensure that BL1 branches to the warm
+boot entrypoint by arranging for the BL1 platform function,
+plat_get_my_entrypoint(), to return a non-zero value.
+
+In this case, the warm boot entrypoint must be in AArch32 EL3, little-endian
+data access and all interrupt sources masked:
+
+::
+
+ PSTATE.AIF = 0x7
+ SCTLR.EE = 0
+
+The warm boot entrypoint may be implemented by using TF-A
+``psci_warmboot_entrypoint()`` function. In that case, the platform must fulfil
+the pre-requisites mentioned in the `PSCI Library integration guide`_.
+
+EL3 runtime services framework
+------------------------------
+
+Software executing in the non-secure state and in the secure state at exception
+levels lower than EL3 will request runtime services using the Secure Monitor
+Call (SMC) instruction. These requests will follow the convention described in
+the SMC Calling Convention PDD (`SMCCC`_). The `SMCCC`_ assigns function
+identifiers to each SMC request and describes how arguments are passed and
+returned.
+
+The EL3 runtime services framework enables the development of services by
+different providers that can be easily integrated into final product firmware.
+The following sections describe the framework which facilitates the
+registration, initialization and use of runtime services in EL3 Runtime
+Software (BL31).
+
+The design of the runtime services depends heavily on the concepts and
+definitions described in the `SMCCC`_, in particular SMC Function IDs, Owning
+Entity Numbers (OEN), Fast and Yielding calls, and the SMC32 and SMC64 calling
+conventions. Please refer to that document for more detailed explanation of
+these terms.
+
+The following runtime services are expected to be implemented first. They have
+not all been instantiated in the current implementation.
+
+#. Standard service calls
+
+ This service is for management of the entire system. The Power State
+ Coordination Interface (`PSCI`_) is the first set of standard service calls
+ defined by Arm (see PSCI section later).
+
+#. Secure-EL1 Payload Dispatcher service
+
+ If a system runs a Trusted OS or other Secure-EL1 Payload (SP) then
+ it also requires a *Secure Monitor* at EL3 to switch the EL1 processor
+ context between the normal world (EL1/EL2) and trusted world (Secure-EL1).
+ The Secure Monitor will make these world switches in response to SMCs. The
+ `SMCCC`_ provides for such SMCs with the Trusted OS Call and Trusted
+ Application Call OEN ranges.
+
+ The interface between the EL3 Runtime Software and the Secure-EL1 Payload is
+ not defined by the `SMCCC`_ or any other standard. As a result, each
+ Secure-EL1 Payload requires a specific Secure Monitor that runs as a runtime
+ service - within TF-A this service is referred to as the Secure-EL1 Payload
+ Dispatcher (SPD).
+
+ TF-A provides a Test Secure-EL1 Payload (TSP) and its associated Dispatcher
+ (TSPD). Details of SPD design and TSP/TSPD operation are described in the
+ "Secure-EL1 Payloads and Dispatchers" section below.
+
+#. CPU implementation service
+
+ This service will provide an interface to CPU implementation specific
+ services for a given platform e.g. access to processor errata workarounds.
+ This service is currently unimplemented.
+
+Additional services for Arm Architecture, SiP and OEM calls can be implemented.
+Each implemented service handles a range of SMC function identifiers as
+described in the `SMCCC`_.
+
+Registration
+~~~~~~~~~~~~
+
+A runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying
+the name of the service, the range of OENs covered, the type of service and
+initialization and call handler functions. This macro instantiates a ``const struct rt_svc_desc`` for the service with these details (see ``runtime_svc.h``).
+This structure is allocated in a special ELF section ``rt_svc_descs``, enabling
+the framework to find all service descriptors included into BL31.
+
+The specific service for a SMC Function is selected based on the OEN and call
+type of the Function ID, and the framework uses that information in the service
+descriptor to identify the handler for the SMC Call.
+
+The service descriptors do not include information to identify the precise set
+of SMC function identifiers supported by this service implementation, the
+security state from which such calls are valid nor the capability to support
+64-bit and/or 32-bit callers (using SMC32 or SMC64). Responding appropriately
+to these aspects of a SMC call is the responsibility of the service
+implementation, the framework is focused on integration of services from
+different providers and minimizing the time taken by the framework before the
+service handler is invoked.
+
+Details of the parameters, requirements and behavior of the initialization and
+call handling functions are provided in the following sections.
+
+Initialization
+~~~~~~~~~~~~~~
+
+``runtime_svc_init()`` in ``runtime_svc.c`` initializes the runtime services
+framework running on the primary CPU during cold boot as part of the BL31
+initialization. This happens prior to initializing a Trusted OS and running
+Normal world boot firmware that might in turn use these services.
+Initialization involves validating each of the declared runtime service
+descriptors, calling the service initialization function and populating the
+index used for runtime lookup of the service.
+
+The BL31 linker script collects all of the declared service descriptors into a
+single array and defines symbols that allow the framework to locate and traverse
+the array, and determine its size.
+
+The framework does basic validation of each descriptor to halt firmware
+initialization if service declaration errors are detected. The framework does
+not check descriptors for the following error conditions, and may behave in an
+unpredictable manner under such scenarios:
+
+#. Overlapping OEN ranges
+#. Multiple descriptors for the same range of OENs and ``call_type``
+#. Incorrect range of owning entity numbers for a given ``call_type``
+
+Once validated, the service ``init()`` callback is invoked. This function carries
+out any essential EL3 initialization before servicing requests. The ``init()``
+function is only invoked on the primary CPU during cold boot. If the service
+uses per-CPU data this must either be initialized for all CPUs during this call,
+or be done lazily when a CPU first issues an SMC call to that service. If
+``init()`` returns anything other than ``0``, this is treated as an initialization
+error and the service is ignored: this does not cause the firmware to halt.
+
+The OEN and call type fields present in the SMC Function ID cover a total of
+128 distinct services, but in practice a single descriptor can cover a range of
+OENs, e.g. SMCs to call a Trusted OS function. To optimize the lookup of a
+service handler, the framework uses an array of 128 indices that map every
+distinct OEN/call-type combination either to one of the declared services or to
+indicate the service is not handled. This ``rt_svc_descs_indices[]`` array is
+populated for all of the OENs covered by a service after the service ``init()``
+function has reported success. So a service that fails to initialize will never
+have it's ``handle()`` function invoked.
+
+The following figure shows how the ``rt_svc_descs_indices[]`` index maps the SMC
+Function ID call type and OEN onto a specific service handler in the
+``rt_svc_descs[]`` array.
+
+|Image 1|
+
+Handling an SMC
+~~~~~~~~~~~~~~~
+
+When the EL3 runtime services framework receives a Secure Monitor Call, the SMC
+Function ID is passed in W0 from the lower exception level (as per the
+`SMCCC`_). If the calling register width is AArch32, it is invalid to invoke an
+SMC Function which indicates the SMC64 calling convention: such calls are
+ignored and return the Unknown SMC Function Identifier result code ``0xFFFFFFFF``
+in R0/X0.
+
+Bit[31] (fast/yielding call) and bits[29:24] (owning entity number) of the SMC
+Function ID are combined to index into the ``rt_svc_descs_indices[]`` array. The
+resulting value might indicate a service that has no handler, in this case the
+framework will also report an Unknown SMC Function ID. Otherwise, the value is
+used as a further index into the ``rt_svc_descs[]`` array to locate the required
+service and handler.
+
+The service's ``handle()`` callback is provided with five of the SMC parameters
+directly, the others are saved into memory for retrieval (if needed) by the
+handler. The handler is also provided with an opaque ``handle`` for use with the
+supporting library for parameter retrieval, setting return values and context
+manipulation; and with ``flags`` indicating the security state of the caller. The
+framework finally sets up the execution stack for the handler, and invokes the
+services ``handle()`` function.
+
+On return from the handler the result registers are populated in X0-X3 before
+restoring the stack and CPU state and returning from the original SMC.
+
+Exception Handling Framework
+----------------------------
+
+Please refer to the `Exception Handling Framework`_ document.
+
+Power State Coordination Interface
+----------------------------------
+
+TODO: Provide design walkthrough of PSCI implementation.
+
+The PSCI v1.1 specification categorizes APIs as optional and mandatory. All the
+mandatory APIs in PSCI v1.1, PSCI v1.0 and in PSCI v0.2 draft specification
+`Power State Coordination Interface PDD`_ are implemented. The table lists
+the PSCI v1.1 APIs and their support in generic code.
+
+An API implementation might have a dependency on platform code e.g. CPU_SUSPEND
+requires the platform to export a part of the implementation. Hence the level
+of support of the mandatory APIs depends upon the support exported by the
+platform port as well. The Juno and FVP (all variants) platforms export all the
+required support.
+
++-----------------------------+-------------+-------------------------------+
+| PSCI v1.1 API | Supported | Comments |
++=============================+=============+===============================+
+| ``PSCI_VERSION`` | Yes | The version returned is 1.1 |
++-----------------------------+-------------+-------------------------------+
+| ``CPU_SUSPEND`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``CPU_OFF`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``CPU_ON`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``AFFINITY_INFO`` | Yes | |
++-----------------------------+-------------+-------------------------------+
+| ``MIGRATE`` | Yes\*\* | |
++-----------------------------+-------------+-------------------------------+
+| ``MIGRATE_INFO_TYPE`` | Yes\*\* | |
++-----------------------------+-------------+-------------------------------+
+| ``MIGRATE_INFO_CPU`` | Yes\*\* | |
++-----------------------------+-------------+-------------------------------+
+| ``SYSTEM_OFF`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``SYSTEM_RESET`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``PSCI_FEATURES`` | Yes | |
++-----------------------------+-------------+-------------------------------+
+| ``CPU_FREEZE`` | No | |
++-----------------------------+-------------+-------------------------------+
+| ``CPU_DEFAULT_SUSPEND`` | No | |
++-----------------------------+-------------+-------------------------------+
+| ``NODE_HW_STATE`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``SYSTEM_SUSPEND`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``PSCI_SET_SUSPEND_MODE`` | No | |
++-----------------------------+-------------+-------------------------------+
+| ``PSCI_STAT_RESIDENCY`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``PSCI_STAT_COUNT`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``SYSTEM_RESET2`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``MEM_PROTECT`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+| ``MEM_PROTECT_CHECK_RANGE`` | Yes\* | |
++-----------------------------+-------------+-------------------------------+
+
+\*Note : These PSCI APIs require platform power management hooks to be
+registered with the generic PSCI code to be supported.
+
+\*\*Note : These PSCI APIs require appropriate Secure Payload Dispatcher
+hooks to be registered with the generic PSCI code to be supported.
+
+The PSCI implementation in TF-A is a library which can be integrated with
+AArch64 or AArch32 EL3 Runtime Software for Armv8-A systems. A guide to
+integrating PSCI library with AArch32 EL3 Runtime Software can be found
+`here`_.
+
+Secure-EL1 Payloads and Dispatchers
+-----------------------------------
+
+On a production system that includes a Trusted OS running in Secure-EL1/EL0,
+the Trusted OS is coupled with a companion runtime service in the BL31
+firmware. This service is responsible for the initialisation of the Trusted
+OS and all communications with it. The Trusted OS is the BL32 stage of the
+boot flow in TF-A. The firmware will attempt to locate, load and execute a
+BL32 image.
+
+TF-A uses a more general term for the BL32 software that runs at Secure-EL1 -
+the *Secure-EL1 Payload* - as it is not always a Trusted OS.
+
+TF-A provides a Test Secure-EL1 Payload (TSP) and a Test Secure-EL1 Payload
+Dispatcher (TSPD) service as an example of how a Trusted OS is supported on a
+production system using the Runtime Services Framework. On such a system, the
+Test BL32 image and service are replaced by the Trusted OS and its dispatcher
+service. The TF-A build system expects that the dispatcher will define the
+build flag ``NEED_BL32`` to enable it to include the BL32 in the build either
+as a binary or to compile from source depending on whether the ``BL32`` build
+option is specified or not.
+
+The TSP runs in Secure-EL1. It is designed to demonstrate synchronous
+communication with the normal-world software running in EL1/EL2. Communication
+is initiated by the normal-world software
+
+- either directly through a Fast SMC (as defined in the `SMCCC`_)
+
+- or indirectly through a `PSCI`_ SMC. The `PSCI`_ implementation in turn
+ informs the TSPD about the requested power management operation. This allows
+ the TSP to prepare for or respond to the power state change
+
+The TSPD service is responsible for.
+
+- Initializing the TSP
+
+- Routing requests and responses between the secure and the non-secure
+ states during the two types of communications just described
+
+Initializing a BL32 Image
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Secure-EL1 Payload Dispatcher (SPD) service is responsible for initializing
+the BL32 image. It needs access to the information passed by BL2 to BL31 to do
+so. This is provided by:
+
+.. code:: c
+
+ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t);
+
+which returns a reference to the ``entry_point_info`` structure corresponding to
+the image which will be run in the specified security state. The SPD uses this
+API to get entry point information for the SECURE image, BL32.
+
+In the absence of a BL32 image, BL31 passes control to the normal world
+bootloader image (BL33). When the BL32 image is present, it is typical
+that the SPD wants control to be passed to BL32 first and then later to BL33.
+
+To do this the SPD has to register a BL32 initialization function during
+initialization of the SPD service. The BL32 initialization function has this
+prototype:
+
+.. code:: c
+
+ int32_t init(void);
+
+and is registered using the ``bl31_register_bl32_init()`` function.
+
+TF-A supports two approaches for the SPD to pass control to BL32 before
+returning through EL3 and running the non-trusted firmware (BL33):
+
+#. In the BL32 setup function, use ``bl31_set_next_image_type()`` to
+ request that the exit from ``bl31_main()`` is to the BL32 entrypoint in
+ Secure-EL1. BL31 will exit to BL32 using the asynchronous method by
+ calling ``bl31_prepare_next_image_entry()`` and ``el3_exit()``.
+
+ When the BL32 has completed initialization at Secure-EL1, it returns to
+ BL31 by issuing an SMC, using a Function ID allocated to the SPD. On
+ receipt of this SMC, the SPD service handler should switch the CPU context
+ from trusted to normal world and use the ``bl31_set_next_image_type()`` and
+ ``bl31_prepare_next_image_entry()`` functions to set up the initial return to
+ the normal world firmware BL33. On return from the handler the framework
+ will exit to EL2 and run BL33.
+
+#. The BL32 setup function registers an initialization function using
+ ``bl31_register_bl32_init()`` which provides a SPD-defined mechanism to
+ invoke a 'world-switch synchronous call' to Secure-EL1 to run the BL32
+ entrypoint.
+ NOTE: The Test SPD service included with TF-A provides one implementation
+ of such a mechanism.
+
+ On completion BL32 returns control to BL31 via a SMC, and on receipt the
+ SPD service handler invokes the synchronous call return mechanism to return
+ to the BL32 initialization function. On return from this function,
+ ``bl31_main()`` will set up the return to the normal world firmware BL33 and
+ continue the boot process in the normal world.
+
+Crash Reporting in BL31
+-----------------------
+
+BL31 implements a scheme for reporting the processor state when an unhandled
+exception is encountered. The reporting mechanism attempts to preserve all the
+register contents and report it via a dedicated UART (PL011 console). BL31
+reports the general purpose, EL3, Secure EL1 and some EL2 state registers.
+
+A dedicated per-CPU crash stack is maintained by BL31 and this is retrieved via
+the per-CPU pointer cache. The implementation attempts to minimise the memory
+required for this feature. The file ``crash_reporting.S`` contains the
+implementation for crash reporting.
+
+The sample crash output is shown below.
+
+::
+
+ x0 :0x000000004F00007C
+ x1 :0x0000000007FFFFFF
+ x2 :0x0000000004014D50
+ x3 :0x0000000000000000
+ x4 :0x0000000088007998
+ x5 :0x00000000001343AC
+ x6 :0x0000000000000016
+ x7 :0x00000000000B8A38
+ x8 :0x00000000001343AC
+ x9 :0x00000000000101A8
+ x10 :0x0000000000000002
+ x11 :0x000000000000011C
+ x12 :0x00000000FEFDC644
+ x13 :0x00000000FED93FFC
+ x14 :0x0000000000247950
+ x15 :0x00000000000007A2
+ x16 :0x00000000000007A4
+ x17 :0x0000000000247950
+ x18 :0x0000000000000000
+ x19 :0x00000000FFFFFFFF
+ x20 :0x0000000004014D50
+ x21 :0x000000000400A38C
+ x22 :0x0000000000247950
+ x23 :0x0000000000000010
+ x24 :0x0000000000000024
+ x25 :0x00000000FEFDC868
+ x26 :0x00000000FEFDC86A
+ x27 :0x00000000019EDEDC
+ x28 :0x000000000A7CFDAA
+ x29 :0x0000000004010780
+ x30 :0x000000000400F004
+ scr_el3 :0x0000000000000D3D
+ sctlr_el3 :0x0000000000C8181F
+ cptr_el3 :0x0000000000000000
+ tcr_el3 :0x0000000080803520
+ daif :0x00000000000003C0
+ mair_el3 :0x00000000000004FF
+ spsr_el3 :0x00000000800003CC
+ elr_el3 :0x000000000400C0CC
+ ttbr0_el3 :0x00000000040172A0
+ esr_el3 :0x0000000096000210
+ sp_el3 :0x0000000004014D50
+ far_el3 :0x000000004F00007C
+ spsr_el1 :0x0000000000000000
+ elr_el1 :0x0000000000000000
+ spsr_abt :0x0000000000000000
+ spsr_und :0x0000000000000000
+ spsr_irq :0x0000000000000000
+ spsr_fiq :0x0000000000000000
+ sctlr_el1 :0x0000000030C81807
+ actlr_el1 :0x0000000000000000
+ cpacr_el1 :0x0000000000300000
+ csselr_el1 :0x0000000000000002
+ sp_el1 :0x0000000004028800
+ esr_el1 :0x0000000000000000
+ ttbr0_el1 :0x000000000402C200
+ ttbr1_el1 :0x0000000000000000
+ mair_el1 :0x00000000000004FF
+ amair_el1 :0x0000000000000000
+ tcr_el1 :0x0000000000003520
+ tpidr_el1 :0x0000000000000000
+ tpidr_el0 :0x0000000000000000
+ tpidrro_el0 :0x0000000000000000
+ dacr32_el2 :0x0000000000000000
+ ifsr32_el2 :0x0000000000000000
+ par_el1 :0x0000000000000000
+ far_el1 :0x0000000000000000
+ afsr0_el1 :0x0000000000000000
+ afsr1_el1 :0x0000000000000000
+ contextidr_el1 :0x0000000000000000
+ vbar_el1 :0x0000000004027000
+ cntp_ctl_el0 :0x0000000000000000
+ cntp_cval_el0 :0x0000000000000000
+ cntv_ctl_el0 :0x0000000000000000
+ cntv_cval_el0 :0x0000000000000000
+ cntkctl_el1 :0x0000000000000000
+ sp_el0 :0x0000000004010780
+
+Guidelines for Reset Handlers
+-----------------------------
+
+TF-A implements a framework that allows CPU and platform ports to perform
+actions very early after a CPU is released from reset in both the cold and warm
+boot paths. This is done by calling the ``reset_handler()`` function in both
+the BL1 and BL31 images. It in turn calls the platform and CPU specific reset
+handling functions.
+
+Details for implementing a CPU specific reset handler can be found in
+Section 8. Details for implementing a platform specific reset handler can be
+found in the `Porting Guide`_ (see the ``plat_reset_handler()`` function).
+
+When adding functionality to a reset handler, keep in mind that if a different
+reset handling behavior is required between the first and the subsequent
+invocations of the reset handling code, this should be detected at runtime.
+In other words, the reset handler should be able to detect whether an action has
+already been performed and act as appropriate. Possible courses of actions are,
+e.g. skip the action the second time, or undo/redo it.
+
+Configuring secure interrupts
+-----------------------------
+
+The GIC driver is responsible for performing initial configuration of secure
+interrupts on the platform. To this end, the platform is expected to provide the
+GIC driver (either GICv2 or GICv3, as selected by the platform) with the
+interrupt configuration during the driver initialisation.
+
+Secure interrupt configuration are specified in an array of secure interrupt
+properties. In this scheme, in both GICv2 and GICv3 driver data structures, the
+``interrupt_props`` member points to an array of interrupt properties. Each
+element of the array specifies the interrupt number and its attributes
+(priority, group, configuration). Each element of the array shall be populated
+by the macro ``INTR_PROP_DESC()``. The macro takes the following arguments:
+
+- 10-bit interrupt number,
+
+- 8-bit interrupt priority,
+
+- Interrupt type (one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1``,
+ ``INTR_TYPE_NS``),
+
+- Interrupt configuration (either ``GIC_INTR_CFG_LEVEL`` or
+ ``GIC_INTR_CFG_EDGE``).
+
+CPU specific operations framework
+---------------------------------
+
+Certain aspects of the Armv8-A architecture are implementation defined,
+that is, certain behaviours are not architecturally defined, but must be
+defined and documented by individual processor implementations. TF-A
+implements a framework which categorises the common implementation defined
+behaviours and allows a processor to export its implementation of that
+behaviour. The categories are:
+
+#. Processor specific reset sequence.
+
+#. Processor specific power down sequences.
+
+#. Processor specific register dumping as a part of crash reporting.
+
+#. Errata status reporting.
+
+Each of the above categories fulfils a different requirement.
+
+#. allows any processor specific initialization before the caches and MMU
+ are turned on, like implementation of errata workarounds, entry into
+ the intra-cluster coherency domain etc.
+
+#. allows each processor to implement the power down sequence mandated in
+ its Technical Reference Manual (TRM).
+
+#. allows a processor to provide additional information to the developer
+ in the event of a crash, for example Cortex-A53 has registers which
+ can expose the data cache contents.
+
+#. allows a processor to define a function that inspects and reports the status
+ of all errata workarounds on that processor.
+
+Please note that only 2. is mandated by the TRM.
+
+The CPU specific operations framework scales to accommodate a large number of
+different CPUs during power down and reset handling. The platform can specify
+any CPU optimization it wants to enable for each CPU. It can also specify
+the CPU errata workarounds to be applied for each CPU type during reset
+handling by defining CPU errata compile time macros. Details on these macros
+can be found in the `cpu-specific-build-macros.rst`_ file.
+
+The CPU specific operations framework depends on the ``cpu_ops`` structure which
+needs to be exported for each type of CPU in the platform. It is defined in
+``include/lib/cpus/aarch64/cpu_macros.S`` and has the following fields : ``midr``,
+``reset_func()``, ``cpu_pwr_down_ops`` (array of power down functions) and
+``cpu_reg_dump()``.
+
+The CPU specific files in ``lib/cpus`` export a ``cpu_ops`` data structure with
+suitable handlers for that CPU. For example, ``lib/cpus/aarch64/cortex_a53.S``
+exports the ``cpu_ops`` for Cortex-A53 CPU. According to the platform
+configuration, these CPU specific files must be included in the build by
+the platform makefile. The generic CPU specific operations framework code exists
+in ``lib/cpus/aarch64/cpu_helpers.S``.
+
+CPU specific Reset Handling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After a reset, the state of the CPU when it calls generic reset handler is:
+MMU turned off, both instruction and data caches turned off and not part
+of any coherency domain.
+
+The BL entrypoint code first invokes the ``plat_reset_handler()`` to allow
+the platform to perform any system initialization required and any system
+errata workarounds that needs to be applied. The ``get_cpu_ops_ptr()`` reads
+the current CPU midr, finds the matching ``cpu_ops`` entry in the ``cpu_ops``
+array and returns it. Note that only the part number and implementer fields
+in midr are used to find the matching ``cpu_ops`` entry. The ``reset_func()`` in
+the returned ``cpu_ops`` is then invoked which executes the required reset
+handling for that CPU and also any errata workarounds enabled by the platform.
+This function must preserve the values of general purpose registers x20 to x29.
+
+Refer to Section "Guidelines for Reset Handlers" for general guidelines
+regarding placement of code in a reset handler.
+
+CPU specific power down sequence
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+During the BL31 initialization sequence, the pointer to the matching ``cpu_ops``
+entry is stored in per-CPU data by ``init_cpu_ops()`` so that it can be quickly
+retrieved during power down sequences.
+
+Various CPU drivers register handlers to perform power down at certain power
+levels for that specific CPU. The PSCI service, upon receiving a power down
+request, determines the highest power level at which to execute power down
+sequence for a particular CPU. It uses the ``prepare_cpu_pwr_dwn()`` function to
+pick the right power down handler for the requested level. The function
+retrieves ``cpu_ops`` pointer member of per-CPU data, and from that, further
+retrieves ``cpu_pwr_down_ops`` array, and indexes into the required level. If the
+requested power level is higher than what a CPU driver supports, the handler
+registered for highest level is invoked.
+
+At runtime the platform hooks for power down are invoked by the PSCI service to
+perform platform specific operations during a power down sequence, for example
+turning off CCI coherency during a cluster power down.
+
+CPU specific register reporting during crash
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If the crash reporting is enabled in BL31, when a crash occurs, the crash
+reporting framework calls ``do_cpu_reg_dump`` which retrieves the matching
+``cpu_ops`` using ``get_cpu_ops_ptr()`` function. The ``cpu_reg_dump()`` in
+``cpu_ops`` is invoked, which then returns the CPU specific register values to
+be reported and a pointer to the ASCII list of register names in a format
+expected by the crash reporting framework.
+
+CPU errata status reporting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Errata workarounds for CPUs supported in TF-A are applied during both cold and
+warm boots, shortly after reset. Individual Errata workarounds are enabled as
+build options. Some errata workarounds have potential run-time implications;
+therefore some are enabled by default, others not. Platform ports shall
+override build options to enable or disable errata as appropriate. The CPU
+drivers take care of applying errata workarounds that are enabled and applicable
+to a given CPU. Refer to the section titled *CPU Errata Workarounds* in `CPUBM`_
+for more information.
+
+Functions in CPU drivers that apply errata workaround must follow the
+conventions listed below.
+
+The errata workaround must be authored as two separate functions:
+
+- One that checks for errata. This function must determine whether that errata
+ applies to the current CPU. Typically this involves matching the current
+ CPUs revision and variant against a value that's known to be affected by the
+ errata. If the function determines that the errata applies to this CPU, it
+ must return ``ERRATA_APPLIES``; otherwise, it must return
+ ``ERRATA_NOT_APPLIES``. The utility functions ``cpu_get_rev_var`` and
+ ``cpu_rev_var_ls`` functions may come in handy for this purpose.
+
+For an errata identified as ``E``, the check function must be named
+``check_errata_E``.
+
+This function will be invoked at different times, both from assembly and from
+C run time. Therefore it must follow AAPCS, and must not use stack.
+
+- Another one that applies the errata workaround. This function would call the
+ check function described above, and applies errata workaround if required.
+
+CPU drivers that apply errata workaround can optionally implement an assembly
+function that report the status of errata workarounds pertaining to that CPU.
+For a driver that registers the CPU, for example, ``cpux`` via ``declare_cpu_ops``
+macro, the errata reporting function, if it exists, must be named
+``cpux_errata_report``. This function will always be called with MMU enabled; it
+must follow AAPCS and may use stack.
+
+In a debug build of TF-A, on a CPU that comes out of reset, both BL1 and the
+runtime firmware (BL31 in AArch64, and BL32 in AArch32) will invoke errata
+status reporting function, if one exists, for that type of CPU.
+
+To report the status of each errata workaround, the function shall use the
+assembler macro ``report_errata``, passing it:
+
+- The build option that enables the errata;
+
+- The name of the CPU: this must be the same identifier that CPU driver
+ registered itself with, using ``declare_cpu_ops``;
+
+- And the errata identifier: the identifier must match what's used in the
+ errata's check function described above.
+
+The errata status reporting function will be called once per CPU type/errata
+combination during the software's active life time.
+
+It's expected that whenever an errata workaround is submitted to TF-A, the
+errata reporting function is appropriately extended to report its status as
+well.
+
+Reporting the status of errata workaround is for informational purpose only; it
+has no functional significance.
+
+Memory layout of BL images
+--------------------------
+
+Each bootloader image can be divided in 2 parts:
+
+- the static contents of the image. These are data actually stored in the
+ binary on the disk. In the ELF terminology, they are called ``PROGBITS``
+ sections;
+
+- the run-time contents of the image. These are data that don't occupy any
+ space in the binary on the disk. The ELF binary just contains some
+ metadata indicating where these data will be stored at run-time and the
+ corresponding sections need to be allocated and initialized at run-time.
+ In the ELF terminology, they are called ``NOBITS`` sections.
+
+All PROGBITS sections are grouped together at the beginning of the image,
+followed by all NOBITS sections. This is true for all TF-A images and it is
+governed by the linker scripts. This ensures that the raw binary images are
+as small as possible. If a NOBITS section was inserted in between PROGBITS
+sections then the resulting binary file would contain zero bytes in place of
+this NOBITS section, making the image unnecessarily bigger. Smaller images
+allow faster loading from the FIP to the main memory.
+
+Linker scripts and symbols
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each bootloader stage image layout is described by its own linker script. The
+linker scripts export some symbols into the program symbol table. Their values
+correspond to particular addresses. TF-A code can refer to these symbols to
+figure out the image memory layout.
+
+Linker symbols follow the following naming convention in TF-A.
+
+- ``__<SECTION>_START__``
+
+ Start address of a given section named ``<SECTION>``.
+
+- ``__<SECTION>_END__``
+
+ End address of a given section named ``<SECTION>``. If there is an alignment
+ constraint on the section's end address then ``__<SECTION>_END__`` corresponds
+ to the end address of the section's actual contents, rounded up to the right
+ boundary. Refer to the value of ``__<SECTION>_UNALIGNED_END__`` to know the
+ actual end address of the section's contents.
+
+- ``__<SECTION>_UNALIGNED_END__``
+
+ End address of a given section named ``<SECTION>`` without any padding or
+ rounding up due to some alignment constraint.
+
+- ``__<SECTION>_SIZE__``
+
+ Size (in bytes) of a given section named ``<SECTION>``. If there is an
+ alignment constraint on the section's end address then ``__<SECTION>_SIZE__``
+ corresponds to the size of the section's actual contents, rounded up to the
+ right boundary. In other words, ``__<SECTION>_SIZE__ = __<SECTION>_END__ - _<SECTION>_START__``. Refer to the value of ``__<SECTION>_UNALIGNED_SIZE__``
+ to know the actual size of the section's contents.
+
+- ``__<SECTION>_UNALIGNED_SIZE__``
+
+ Size (in bytes) of a given section named ``<SECTION>`` without any padding or
+ rounding up due to some alignment constraint. In other words,
+ ``__<SECTION>_UNALIGNED_SIZE__ = __<SECTION>_UNALIGNED_END__ - __<SECTION>_START__``.
+
+Some of the linker symbols are mandatory as TF-A code relies on them to be
+defined. They are listed in the following subsections. Some of them must be
+provided for each bootloader stage and some are specific to a given bootloader
+stage.
+
+The linker scripts define some extra, optional symbols. They are not actually
+used by any code but they help in understanding the bootloader images' memory
+layout as they are easy to spot in the link map files.
+
+Common linker symbols
+^^^^^^^^^^^^^^^^^^^^^
+
+All BL images share the following requirements:
+
+- The BSS section must be zero-initialised before executing any C code.
+- The coherent memory section (if enabled) must be zero-initialised as well.
+- The MMU setup code needs to know the extents of the coherent and read-only
+ memory regions to set the right memory attributes. When
+ ``SEPARATE_CODE_AND_RODATA=1``, it needs to know more specifically how the
+ read-only memory region is divided between code and data.
+
+The following linker symbols are defined for this purpose:
+
+- ``__BSS_START__``
+- ``__BSS_SIZE__``
+- ``__COHERENT_RAM_START__`` Must be aligned on a page-size boundary.
+- ``__COHERENT_RAM_END__`` Must be aligned on a page-size boundary.
+- ``__COHERENT_RAM_UNALIGNED_SIZE__``
+- ``__RO_START__``
+- ``__RO_END__``
+- ``__TEXT_START__``
+- ``__TEXT_END__``
+- ``__RODATA_START__``
+- ``__RODATA_END__``
+
+BL1's linker symbols
+^^^^^^^^^^^^^^^^^^^^
+
+BL1 being the ROM image, it has additional requirements. BL1 resides in ROM and
+it is entirely executed in place but it needs some read-write memory for its
+mutable data. Its ``.data`` section (i.e. its allocated read-write data) must be
+relocated from ROM to RAM before executing any C code.
+
+The following additional linker symbols are defined for BL1:
+
+- ``__BL1_ROM_END__`` End address of BL1's ROM contents, covering its code
+ and ``.data`` section in ROM.
+- ``__DATA_ROM_START__`` Start address of the ``.data`` section in ROM. Must be
+ aligned on a 16-byte boundary.
+- ``__DATA_RAM_START__`` Address in RAM where the ``.data`` section should be
+ copied over. Must be aligned on a 16-byte boundary.
+- ``__DATA_SIZE__`` Size of the ``.data`` section (in ROM or RAM).
+- ``__BL1_RAM_START__`` Start address of BL1 read-write data.
+- ``__BL1_RAM_END__`` End address of BL1 read-write data.
+
+How to choose the right base addresses for each bootloader stage image
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There is currently no support for dynamic image loading in TF-A. This means
+that all bootloader images need to be linked against their ultimate runtime
+locations and the base addresses of each image must be chosen carefully such
+that images don't overlap each other in an undesired way. As the code grows,
+the base addresses might need adjustments to cope with the new memory layout.
+
+The memory layout is completely specific to the platform and so there is no
+general recipe for choosing the right base addresses for each bootloader image.
+However, there are tools to aid in understanding the memory layout. These are
+the link map files: ``build/<platform>/<build-type>/bl<x>/bl<x>.map``, with ``<x>``
+being the stage bootloader. They provide a detailed view of the memory usage of
+each image. Among other useful information, they provide the end address of
+each image.
+
+- ``bl1.map`` link map file provides ``__BL1_RAM_END__`` address.
+- ``bl2.map`` link map file provides ``__BL2_END__`` address.
+- ``bl31.map`` link map file provides ``__BL31_END__`` address.
+- ``bl32.map`` link map file provides ``__BL32_END__`` address.
+
+For each bootloader image, the platform code must provide its start address
+as well as a limit address that it must not overstep. The latter is used in the
+linker scripts to check that the image doesn't grow past that address. If that
+happens, the linker will issue a message similar to the following:
+
+::
+
+ aarch64-none-elf-ld: BLx has exceeded its limit.
+
+Additionally, if the platform memory layout implies some image overlaying like
+on FVP, BL31 and TSP need to know the limit address that their PROGBITS
+sections must not overstep. The platform code must provide those.
+
+TF-A does not provide any mechanism to verify at boot time that the memory
+to load a new image is free to prevent overwriting a previously loaded image.
+The platform must specify the memory available in the system for all the
+relevant BL images to be loaded.
+
+For example, in the case of BL1 loading BL2, ``bl1_plat_sec_mem_layout()`` will
+return the region defined by the platform where BL1 intends to load BL2. The
+``load_image()`` function performs bounds check for the image size based on the
+base and maximum image size provided by the platforms. Platforms must take
+this behaviour into account when defining the base/size for each of the images.
+
+Memory layout on Arm development platforms
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following list describes the memory layout on the Arm development platforms:
+
+- A 4KB page of shared memory is used for communication between Trusted
+ Firmware and the platform's power controller. This is located at the base of
+ Trusted SRAM. The amount of Trusted SRAM available to load the bootloader
+ images is reduced by the size of the shared memory.
+
+ The shared memory is used to store the CPUs' entrypoint mailbox. On Juno,
+ this is also used for the MHU payload when passing messages to and from the
+ SCP.
+
+- Another 4 KB page is reserved for passing memory layout between BL1 and BL2
+ and also the dynamic firmware configurations.
+
+- On FVP, BL1 is originally sitting in the Trusted ROM at address ``0x0``. On
+ Juno, BL1 resides in flash memory at address ``0x0BEC0000``. BL1 read-write
+ data are relocated to the top of Trusted SRAM at runtime.
+
+- BL2 is loaded below BL1 RW
+
+- EL3 Runtime Software, BL31 for AArch64 and BL32 for AArch32 (e.g. SP_MIN),
+ is loaded at the top of the Trusted SRAM, such that its NOBITS sections will
+ overwrite BL1 R/W data and BL2. This implies that BL1 global variables
+ remain valid only until execution reaches the EL3 Runtime Software entry
+ point during a cold boot.
+
+- On Juno, SCP_BL2 is loaded temporarily into the EL3 Runtime Software memory
+ region and transfered to the SCP before being overwritten by EL3 Runtime
+ Software.
+
+- BL32 (for AArch64) can be loaded in one of the following locations:
+
+ - Trusted SRAM
+ - Trusted DRAM (FVP only)
+ - Secure region of DRAM (top 16MB of DRAM configured by the TrustZone
+ controller)
+
+ When BL32 (for AArch64) is loaded into Trusted SRAM, it is loaded below
+ BL31.
+
+The location of the BL32 image will result in different memory maps. This is
+illustrated for both FVP and Juno in the following diagrams, using the TSP as
+an example.
+
+Note: Loading the BL32 image in TZC secured DRAM doesn't change the memory
+layout of the other images in Trusted SRAM.
+
+CONFIG section in memory layouts shown below contains:
+
+::
+
+ +--------------------+
+ |bl2_mem_params_descs|
+ |--------------------|
+ | fw_configs |
+ +--------------------+
+
+``bl2_mem_params_descs`` contains parameters passed from BL2 to next the
+BL image during boot.
+
+``fw_configs`` includes soc_fw_config, tos_fw_config and tb_fw_config.
+
+**FVP with TSP in Trusted SRAM with firmware configs :**
+(These diagrams only cover the AArch64 case)
+
+::
+
+ DRAM
+ 0xffffffff +----------+
+ : :
+ |----------|
+ |HW_CONFIG |
+ 0x83000000 |----------| (non-secure)
+ | |
+ 0x80000000 +----------+
+
+ Trusted SRAM
+ 0x04040000 +----------+ loaded by BL2 +----------------+
+ | BL1 (rw) | <<<<<<<<<<<<< | |
+ |----------| <<<<<<<<<<<<< | BL31 NOBITS |
+ | BL2 | <<<<<<<<<<<<< | |
+ |----------| <<<<<<<<<<<<< |----------------|
+ | | <<<<<<<<<<<<< | BL31 PROGBITS |
+ | | <<<<<<<<<<<<< |----------------|
+ | | <<<<<<<<<<<<< | BL32 |
+ 0x04002000 +----------+ +----------------+
+ | CONFIG |
+ 0x04001000 +----------+
+ | Shared |
+ 0x04000000 +----------+
+
+ Trusted ROM
+ 0x04000000 +----------+
+ | BL1 (ro) |
+ 0x00000000 +----------+
+
+**FVP with TSP in Trusted DRAM with firmware configs (default option):**
+
+::
+
+ DRAM
+ 0xffffffff +--------------+
+ : :
+ |--------------|
+ | HW_CONFIG |
+ 0x83000000 |--------------| (non-secure)
+ | |
+ 0x80000000 +--------------+
+
+ Trusted DRAM
+ 0x08000000 +--------------+
+ | BL32 |
+ 0x06000000 +--------------+
+
+ Trusted SRAM
+ 0x04040000 +--------------+ loaded by BL2 +----------------+
+ | BL1 (rw) | <<<<<<<<<<<<< | |
+ |--------------| <<<<<<<<<<<<< | BL31 NOBITS |
+ | BL2 | <<<<<<<<<<<<< | |
+ |--------------| <<<<<<<<<<<<< |----------------|
+ | | <<<<<<<<<<<<< | BL31 PROGBITS |
+ | | +----------------+
+ +--------------+
+ | CONFIG |
+ 0x04001000 +--------------+
+ | Shared |
+ 0x04000000 +--------------+
+
+ Trusted ROM
+ 0x04000000 +--------------+
+ | BL1 (ro) |
+ 0x00000000 +--------------+
+
+**FVP with TSP in TZC-Secured DRAM with firmware configs :**
+
+::
+
+ DRAM
+ 0xffffffff +----------+
+ | BL32 | (secure)
+ 0xff000000 +----------+
+ | |
+ |----------|
+ |HW_CONFIG |
+ 0x83000000 |----------| (non-secure)
+ | |
+ 0x80000000 +----------+
+
+ Trusted SRAM
+ 0x04040000 +----------+ loaded by BL2 +----------------+
+ | BL1 (rw) | <<<<<<<<<<<<< | |
+ |----------| <<<<<<<<<<<<< | BL31 NOBITS |
+ | BL2 | <<<<<<<<<<<<< | |
+ |----------| <<<<<<<<<<<<< |----------------|
+ | | <<<<<<<<<<<<< | BL31 PROGBITS |
+ | | +----------------+
+ 0x04002000 +----------+
+ | CONFIG |
+ 0x04001000 +----------+
+ | Shared |
+ 0x04000000 +----------+
+
+ Trusted ROM
+ 0x04000000 +----------+
+ | BL1 (ro) |
+ 0x00000000 +----------+
+
+**Juno with BL32 in Trusted SRAM :**
+
+::
+
+ Flash0
+ 0x0C000000 +----------+
+ : :
+ 0x0BED0000 |----------|
+ | BL1 (ro) |
+ 0x0BEC0000 |----------|
+ : :
+ 0x08000000 +----------+ BL31 is loaded
+ after SCP_BL2 has
+ Trusted SRAM been sent to SCP
+ 0x04040000 +----------+ loaded by BL2 +----------------+
+ | BL1 (rw) | <<<<<<<<<<<<< | |
+ |----------| <<<<<<<<<<<<< | BL31 NOBITS |
+ | BL2 | <<<<<<<<<<<<< | |
+ |----------| <<<<<<<<<<<<< |----------------|
+ | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS |
+ |----------| <<<<<<<<<<<<< |----------------|
+ | | <<<<<<<<<<<<< | BL32 |
+ | | +----------------+
+ | |
+ 0x04001000 +----------+
+ | MHU |
+ 0x04000000 +----------+
+
+**Juno with BL32 in TZC-secured DRAM :**
+
+::
+
+ DRAM
+ 0xFFE00000 +----------+
+ | BL32 | (secure)
+ 0xFF000000 |----------|
+ | |
+ : : (non-secure)
+ | |
+ 0x80000000 +----------+
+
+ Flash0
+ 0x0C000000 +----------+
+ : :
+ 0x0BED0000 |----------|
+ | BL1 (ro) |
+ 0x0BEC0000 |----------|
+ : :
+ 0x08000000 +----------+ BL31 is loaded
+ after SCP_BL2 has
+ Trusted SRAM been sent to SCP
+ 0x04040000 +----------+ loaded by BL2 +----------------+
+ | BL1 (rw) | <<<<<<<<<<<<< | |
+ |----------| <<<<<<<<<<<<< | BL31 NOBITS |
+ | BL2 | <<<<<<<<<<<<< | |
+ |----------| <<<<<<<<<<<<< |----------------|
+ | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS |
+ |----------| +----------------+
+ 0x04001000 +----------+
+ | MHU |
+ 0x04000000 +----------+
+
+Library at ROM
+---------------
+
+Please refer to the `ROMLIB Design`_ document.
+
+Firmware Image Package (FIP)
+----------------------------
+
+Using a Firmware Image Package (FIP) allows for packing bootloader images (and
+potentially other payloads) into a single archive that can be loaded by TF-A
+from non-volatile platform storage. A driver to load images from a FIP has
+been added to the storage layer and allows a package to be read from supported
+platform storage. A tool to create Firmware Image Packages is also provided
+and described below.
+
+Firmware Image Package layout
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The FIP layout consists of a table of contents (ToC) followed by payload data.
+The ToC itself has a header followed by one or more table entries. The ToC is
+terminated by an end marker entry, and since the size of the ToC is 0 bytes,
+the offset equals the total size of the FIP file. All ToC entries describe some
+payload data that has been appended to the end of the binary package. With the
+information provided in the ToC entry the corresponding payload data can be
+retrieved.
+
+::
+
+ ------------------
+ | ToC Header |
+ |----------------|
+ | ToC Entry 0 |
+ |----------------|
+ | ToC Entry 1 |
+ |----------------|
+ | ToC End Marker |
+ |----------------|
+ | |
+ | Data 0 |
+ | |
+ |----------------|
+ | |
+ | Data 1 |
+ | |
+ ------------------
+
+The ToC header and entry formats are described in the header file
+``include/tools_share/firmware_image_package.h``. This file is used by both the
+tool and TF-A.
+
+The ToC header has the following fields:
+
+::
+
+ `name`: The name of the ToC. This is currently used to validate the header.
+ `serial_number`: A non-zero number provided by the creation tool
+ `flags`: Flags associated with this data.
+ Bits 0-31: Reserved
+ Bits 32-47: Platform defined
+ Bits 48-63: Reserved
+
+A ToC entry has the following fields:
+
+::
+
+ `uuid`: All files are referred to by a pre-defined Universally Unique
+ IDentifier [UUID] . The UUIDs are defined in
+ `include/tools_share/firmware_image_package.h`. The platform translates
+ the requested image name into the corresponding UUID when accessing the
+ package.
+ `offset_address`: The offset address at which the corresponding payload data
+ can be found. The offset is calculated from the ToC base address.
+ `size`: The size of the corresponding payload data in bytes.
+ `flags`: Flags associated with this entry. None are yet defined.
+
+Firmware Image Package creation tool
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The FIP creation tool can be used to pack specified images into a binary
+package that can be loaded by TF-A from platform storage. The tool currently
+only supports packing bootloader images. Additional image definitions can be
+added to the tool as required.
+
+The tool can be found in ``tools/fiptool``.
+
+Loading from a Firmware Image Package (FIP)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Firmware Image Package (FIP) driver can load images from a binary package on
+non-volatile platform storage. For the Arm development platforms, this is
+currently NOR FLASH.
+
+Bootloader images are loaded according to the platform policy as specified by
+the function ``plat_get_image_source()``. For the Arm development platforms, this
+means the platform will attempt to load images from a Firmware Image Package
+located at the start of NOR FLASH0.
+
+The Arm development platforms' policy is to only allow loading of a known set of
+images. The platform policy can be modified to allow additional images.
+
+Use of coherent memory in TF-A
+------------------------------
+
+There might be loss of coherency when physical memory with mismatched
+shareability, cacheability and memory attributes is accessed by multiple CPUs
+(refer to section B2.9 of `Arm ARM`_ for more details). This possibility occurs
+in TF-A during power up/down sequences when coherency, MMU and caches are
+turned on/off incrementally.
+
+TF-A defines coherent memory as a region of memory with Device nGnRE attributes
+in the translation tables. The translation granule size in TF-A is 4KB. This
+is the smallest possible size of the coherent memory region.
+
+By default, all data structures which are susceptible to accesses with
+mismatched attributes from various CPUs are allocated in a coherent memory
+region (refer to section 2.1 of `Porting Guide`_). The coherent memory region
+accesses are Outer Shareable, non-cacheable and they can be accessed
+with the Device nGnRE attributes when the MMU is turned on. Hence, at the
+expense of at least an extra page of memory, TF-A is able to work around
+coherency issues due to mismatched memory attributes.
+
+The alternative to the above approach is to allocate the susceptible data
+structures in Normal WriteBack WriteAllocate Inner shareable memory. This
+approach requires the data structures to be designed so that it is possible to
+work around the issue of mismatched memory attributes by performing software
+cache maintenance on them.
+
+Disabling the use of coherent memory in TF-A
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It might be desirable to avoid the cost of allocating coherent memory on
+platforms which are memory constrained. TF-A enables inclusion of coherent
+memory in firmware images through the build flag ``USE_COHERENT_MEM``.
+This flag is enabled by default. It can be disabled to choose the second
+approach described above.
+
+The below sections analyze the data structures allocated in the coherent memory
+region and the changes required to allocate them in normal memory.
+
+Coherent memory usage in PSCI implementation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``psci_non_cpu_pd_nodes`` data structure stores the platform's power domain
+tree information for state management of power domains. By default, this data
+structure is allocated in the coherent memory region in TF-A because it can be
+accessed by multiple CPUs, either with caches enabled or disabled.
+
+.. code:: c
+
+ typedef struct non_cpu_pwr_domain_node {
+ /*
+ * Index of the first CPU power domain node level 0 which has this node
+ * as its parent.
+ */
+ unsigned int cpu_start_idx;
+
+ /*
+ * Number of CPU power domains which are siblings of the domain indexed
+ * by 'cpu_start_idx' i.e. all the domains in the range 'cpu_start_idx
+ * -> cpu_start_idx + ncpus' have this node as their parent.
+ */
+ unsigned int ncpus;
+
+ /*
+ * Index of the parent power domain node.
+ */
+ unsigned int parent_node;
+
+ plat_local_state_t local_state;
+
+ unsigned char level;
+
+ /* For indexing the psci_lock array*/
+ unsigned char lock_index;
+ } non_cpu_pd_node_t;
+
+In order to move this data structure to normal memory, the use of each of its
+fields must be analyzed. Fields like ``cpu_start_idx``, ``ncpus``, ``parent_node``
+``level`` and ``lock_index`` are only written once during cold boot. Hence removing
+them from coherent memory involves only doing a clean and invalidate of the
+cache lines after these fields are written.
+
+The field ``local_state`` can be concurrently accessed by multiple CPUs in
+different cache states. A Lamport's Bakery lock ``psci_locks`` is used to ensure
+mutual exclusion to this field and a clean and invalidate is needed after it
+is written.
+
+Bakery lock data
+~~~~~~~~~~~~~~~~
+
+The bakery lock data structure ``bakery_lock_t`` is allocated in coherent memory
+and is accessed by multiple CPUs with mismatched attributes. ``bakery_lock_t`` is
+defined as follows:
+
+.. code:: c
+
+ typedef struct bakery_lock {
+ /*
+ * The lock_data is a bit-field of 2 members:
+ * Bit[0] : choosing. This field is set when the CPU is
+ * choosing its bakery number.
+ * Bits[1 - 15] : number. This is the bakery number allocated.
+ */
+ volatile uint16_t lock_data[BAKERY_LOCK_MAX_CPUS];
+ } bakery_lock_t;
+
+It is a characteristic of Lamport's Bakery algorithm that the volatile per-CPU
+fields can be read by all CPUs but only written to by the owning CPU.
+
+Depending upon the data cache line size, the per-CPU fields of the
+``bakery_lock_t`` structure for multiple CPUs may exist on a single cache line.
+These per-CPU fields can be read and written during lock contention by multiple
+CPUs with mismatched memory attributes. Since these fields are a part of the
+lock implementation, they do not have access to any other locking primitive to
+safeguard against the resulting coherency issues. As a result, simple software
+cache maintenance is not enough to allocate them in coherent memory. Consider
+the following example.
+
+CPU0 updates its per-CPU field with data cache enabled. This write updates a
+local cache line which contains a copy of the fields for other CPUs as well. Now
+CPU1 updates its per-CPU field of the ``bakery_lock_t`` structure with data cache
+disabled. CPU1 then issues a DCIVAC operation to invalidate any stale copies of
+its field in any other cache line in the system. This operation will invalidate
+the update made by CPU0 as well.
+
+To use bakery locks when ``USE_COHERENT_MEM`` is disabled, the lock data structure
+has been redesigned. The changes utilise the characteristic of Lamport's Bakery
+algorithm mentioned earlier. The bakery_lock structure only allocates the memory
+for a single CPU. The macro ``DEFINE_BAKERY_LOCK`` allocates all the bakery locks
+needed for a CPU into a section ``bakery_lock``. The linker allocates the memory
+for other cores by using the total size allocated for the bakery_lock section
+and multiplying it with (PLATFORM_CORE_COUNT - 1). This enables software to
+perform software cache maintenance on the lock data structure without running
+into coherency issues associated with mismatched attributes.
+
+The bakery lock data structure ``bakery_info_t`` is defined for use when
+``USE_COHERENT_MEM`` is disabled as follows:
+
+.. code:: c
+
+ typedef struct bakery_info {
+ /*
+ * The lock_data is a bit-field of 2 members:
+ * Bit[0] : choosing. This field is set when the CPU is
+ * choosing its bakery number.
+ * Bits[1 - 15] : number. This is the bakery number allocated.
+ */
+ volatile uint16_t lock_data;
+ } bakery_info_t;
+
+The ``bakery_info_t`` represents a single per-CPU field of one lock and
+the combination of corresponding ``bakery_info_t`` structures for all CPUs in the
+system represents the complete bakery lock. The view in memory for a system
+with n bakery locks are:
+
+::
+
+ bakery_lock section start
+ |----------------|
+ | `bakery_info_t`| <-- Lock_0 per-CPU field
+ | Lock_0 | for CPU0
+ |----------------|
+ | `bakery_info_t`| <-- Lock_1 per-CPU field
+ | Lock_1 | for CPU0
+ |----------------|
+ | .... |
+ |----------------|
+ | `bakery_info_t`| <-- Lock_N per-CPU field
+ | Lock_N | for CPU0
+ ------------------
+ | XXXXX |
+ | Padding to |
+ | next Cache WB | <--- Calculate PERCPU_BAKERY_LOCK_SIZE, allocate
+ | Granule | continuous memory for remaining CPUs.
+ ------------------
+ | `bakery_info_t`| <-- Lock_0 per-CPU field
+ | Lock_0 | for CPU1
+ |----------------|
+ | `bakery_info_t`| <-- Lock_1 per-CPU field
+ | Lock_1 | for CPU1
+ |----------------|
+ | .... |
+ |----------------|
+ | `bakery_info_t`| <-- Lock_N per-CPU field
+ | Lock_N | for CPU1
+ ------------------
+ | XXXXX |
+ | Padding to |
+ | next Cache WB |
+ | Granule |
+ ------------------
+
+Consider a system of 2 CPUs with 'N' bakery locks as shown above. For an
+operation on Lock_N, the corresponding ``bakery_info_t`` in both CPU0 and CPU1
+``bakery_lock`` section need to be fetched and appropriate cache operations need
+to be performed for each access.
+
+On Arm Platforms, bakery locks are used in psci (``psci_locks``) and power controller
+driver (``arm_lock``).
+
+Non Functional Impact of removing coherent memory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Removal of the coherent memory region leads to the additional software overhead
+of performing cache maintenance for the affected data structures. However, since
+the memory where the data structures are allocated is cacheable, the overhead is
+mostly mitigated by an increase in performance.
+
+There is however a performance impact for bakery locks, due to:
+
+- Additional cache maintenance operations, and
+- Multiple cache line reads for each lock operation, since the bakery locks
+ for each CPU are distributed across different cache lines.
+
+The implementation has been optimized to minimize this additional overhead.
+Measurements indicate that when bakery locks are allocated in Normal memory, the
+minimum latency of acquiring a lock is on an average 3-4 micro seconds whereas
+in Device memory the same is 2 micro seconds. The measurements were done on the
+Juno Arm development platform.
+
+As mentioned earlier, almost a page of memory can be saved by disabling
+``USE_COHERENT_MEM``. Each platform needs to consider these trade-offs to decide
+whether coherent memory should be used. If a platform disables
+``USE_COHERENT_MEM`` and needs to use bakery locks in the porting layer, it can
+optionally define macro ``PLAT_PERCPU_BAKERY_LOCK_SIZE`` (see the
+`Porting Guide`_). Refer to the reference platform code for examples.
+
+Isolating code and read-only data on separate memory pages
+----------------------------------------------------------
+
+In the Armv8-A VMSA, translation table entries include fields that define the
+properties of the target memory region, such as its access permissions. The
+smallest unit of memory that can be addressed by a translation table entry is
+a memory page. Therefore, if software needs to set different permissions on two
+memory regions then it needs to map them using different memory pages.
+
+The default memory layout for each BL image is as follows:
+
+::
+
+ | ... |
+ +-------------------+
+ | Read-write data |
+ +-------------------+ Page boundary
+ | <Padding> |
+ +-------------------+
+ | Exception vectors |
+ +-------------------+ 2 KB boundary
+ | <Padding> |
+ +-------------------+
+ | Read-only data |
+ +-------------------+
+ | Code |
+ +-------------------+ BLx_BASE
+
+Note: The 2KB alignment for the exception vectors is an architectural
+requirement.
+
+The read-write data start on a new memory page so that they can be mapped with
+read-write permissions, whereas the code and read-only data below are configured
+as read-only.
+
+However, the read-only data are not aligned on a page boundary. They are
+contiguous to the code. Therefore, the end of the code section and the beginning
+of the read-only data one might share a memory page. This forces both to be
+mapped with the same memory attributes. As the code needs to be executable, this
+means that the read-only data stored on the same memory page as the code are
+executable as well. This could potentially be exploited as part of a security
+attack.
+
+TF provides the build flag ``SEPARATE_CODE_AND_RODATA`` to isolate the code and
+read-only data on separate memory pages. This in turn allows independent control
+of the access permissions for the code and read-only data. In this case,
+platform code gets a finer-grained view of the image layout and can
+appropriately map the code region as executable and the read-only data as
+execute-never.
+
+This has an impact on memory footprint, as padding bytes need to be introduced
+between the code and read-only data to ensure the segregation of the two. To
+limit the memory cost, this flag also changes the memory layout such that the
+code and exception vectors are now contiguous, like so:
+
+::
+
+ | ... |
+ +-------------------+
+ | Read-write data |
+ +-------------------+ Page boundary
+ | <Padding> |
+ +-------------------+
+ | Read-only data |
+ +-------------------+ Page boundary
+ | <Padding> |
+ +-------------------+
+ | Exception vectors |
+ +-------------------+ 2 KB boundary
+ | <Padding> |
+ +-------------------+
+ | Code |
+ +-------------------+ BLx_BASE
+
+With this more condensed memory layout, the separation of read-only data will
+add zero or one page to the memory footprint of each BL image. Each platform
+should consider the trade-off between memory footprint and security.
+
+This build flag is disabled by default, minimising memory footprint. On Arm
+platforms, it is enabled.
+
+Publish and Subscribe Framework
+-------------------------------
+
+The Publish and Subscribe Framework allows EL3 components to define and publish
+events, to which other EL3 components can subscribe.
+
+The following macros are provided by the framework:
+
+- ``REGISTER_PUBSUB_EVENT(event)``: Defines an event, and takes one argument,
+ the event name, which must be a valid C identifier. All calls to
+ ``REGISTER_PUBSUB_EVENT`` macro must be placed in the file
+ ``pubsub_events.h``.
+
+- ``PUBLISH_EVENT_ARG(event, arg)``: Publishes a defined event, by iterating
+ subscribed handlers and calling them in turn. The handlers will be passed the
+ parameter ``arg``. The expected use-case is to broadcast an event.
+
+- ``PUBLISH_EVENT(event)``: Like ``PUBLISH_EVENT_ARG``, except that the value
+ ``NULL`` is passed to subscribed handlers.
+
+- ``SUBSCRIBE_TO_EVENT(event, handler)``: Registers the ``handler`` to
+ subscribe to ``event``. The handler will be executed whenever the ``event``
+ is published.
+
+- ``for_each_subscriber(event, subscriber)``: Iterates through all handlers
+ subscribed for ``event``. ``subscriber`` must be a local variable of type
+ ``pubsub_cb_t *``, and will point to each subscribed handler in turn during
+ iteration. This macro can be used for those patterns that none of the
+ ``PUBLISH_EVENT_*()`` macros cover.
+
+Publishing an event that wasn't defined using ``REGISTER_PUBSUB_EVENT`` will
+result in build error. Subscribing to an undefined event however won't.
+
+Subscribed handlers must be of type ``pubsub_cb_t``, with following function
+signature:
+
+::
+
+ typedef void* (*pubsub_cb_t)(const void *arg);
+
+There may be arbitrary number of handlers registered to the same event. The
+order in which subscribed handlers are notified when that event is published is
+not defined. Subscribed handlers may be executed in any order; handlers should
+not assume any relative ordering amongst them.
+
+Publishing an event on a PE will result in subscribed handlers executing on that
+PE only; it won't cause handlers to execute on a different PE.
+
+Note that publishing an event on a PE blocks until all the subscribed handlers
+finish executing on the PE.
+
+TF-A generic code publishes and subscribes to some events within. Platform
+ports are discouraged from subscribing to them. These events may be withdrawn,
+renamed, or have their semantics altered in the future. Platforms may however
+register, publish, and subscribe to platform-specific events.
+
+Publish and Subscribe Example
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A publisher that wants to publish event ``foo`` would:
+
+- Define the event ``foo`` in the ``pubsub_events.h``.
+
+ ::
+
+ REGISTER_PUBSUB_EVENT(foo);
+
+- Depending on the nature of event, use one of ``PUBLISH_EVENT_*()`` macros to
+ publish the event at the appropriate path and time of execution.
+
+A subscriber that wants to subscribe to event ``foo`` published above would
+implement:
+
+.. code:: c
+
+ void *foo_handler(const void *arg)
+ {
+ void *result;
+
+ /* Do handling ... */
+
+ return result;
+ }
+
+ SUBSCRIBE_TO_EVENT(foo, foo_handler);
+
+
+Reclaiming the BL31 initialization code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A significant amount of the code used for the initialization of BL31 is never
+needed again after boot time. In order to reduce the runtime memory
+footprint, the memory used for this code can be reclaimed after initialization
+has finished and be used for runtime data.
+
+The build option ``RECLAIM_INIT_CODE`` can be set to mark this boot time code
+with a ``.text.init.*`` attribute which can be filtered and placed suitably
+within the BL image for later reclamation by the platform. The platform can
+specify the filter and the memory region for this init section in BL31 via the
+plat.ld.S linker script. For example, on the FVP, this section is placed
+overlapping the secondary CPU stacks so that after the cold boot is done, this
+memory can be reclaimed for the stacks. The init memory section is initially
+mapped with ``RO``, ``EXECUTE`` attributes. After BL31 initialization has
+completed, the FVP changes the attributes of this section to ``RW``,
+``EXECUTE_NEVER`` allowing it to be used for runtime data. The memory attributes
+are changed within the ``bl31_plat_runtime_setup`` platform hook. The init
+section section can be reclaimed for any data which is accessed after cold
+boot initialization and it is upto the platform to make the decision.
+
+Performance Measurement Framework
+---------------------------------
+
+The Performance Measurement Framework (PMF) facilitates collection of
+timestamps by registered services and provides interfaces to retrieve them
+from within TF-A. A platform can choose to expose appropriate SMCs to
+retrieve these collected timestamps.
+
+By default, the global physical counter is used for the timestamp
+value and is read via ``CNTPCT_EL0``. The framework allows to retrieve
+timestamps captured by other CPUs.
+
+Timestamp identifier format
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A PMF timestamp is uniquely identified across the system via the
+timestamp ID or ``tid``. The ``tid`` is composed as follows:
+
+::
+
+ Bits 0-7: The local timestamp identifier.
+ Bits 8-9: Reserved.
+ Bits 10-15: The service identifier.
+ Bits 16-31: Reserved.
+
+#. The service identifier. Each PMF service is identified by a
+ service name and a service identifier. Both the service name and
+ identifier are unique within the system as a whole.
+
+#. The local timestamp identifier. This identifier is unique within a given
+ service.
+
+Registering a PMF service
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To register a PMF service, the ``PMF_REGISTER_SERVICE()`` macro from ``pmf.h``
+is used. The arguments required are the service name, the service ID,
+the total number of local timestamps to be captured and a set of flags.
+
+The ``flags`` field can be specified as a bitwise-OR of the following values:
+
+::
+
+ PMF_STORE_ENABLE: The timestamp is stored in memory for later retrieval.
+ PMF_DUMP_ENABLE: The timestamp is dumped on the serial console.
+
+The ``PMF_REGISTER_SERVICE()`` reserves memory to store captured
+timestamps in a PMF specific linker section at build time.
+Additionally, it defines necessary functions to capture and
+retrieve a particular timestamp for the given service at runtime.
+
+The macro ``PMF_REGISTER_SERVICE()`` only enables capturing PMF timestamps
+from within TF-A. In order to retrieve timestamps from outside of TF-A, the
+``PMF_REGISTER_SERVICE_SMC()`` macro must be used instead. This macro
+accepts the same set of arguments as the ``PMF_REGISTER_SERVICE()``
+macro but additionally supports retrieving timestamps using SMCs.
+
+Capturing a timestamp
+~~~~~~~~~~~~~~~~~~~~~
+
+PMF timestamps are stored in a per-service timestamp region. On a
+system with multiple CPUs, each timestamp is captured and stored
+in a per-CPU cache line aligned memory region.
+
+Having registered the service, the ``PMF_CAPTURE_TIMESTAMP()`` macro can be
+used to capture a timestamp at the location where it is used. The macro
+takes the service name, a local timestamp identifier and a flag as arguments.
+
+The ``flags`` field argument can be zero, or ``PMF_CACHE_MAINT`` which
+instructs PMF to do cache maintenance following the capture. Cache
+maintenance is required if any of the service's timestamps are captured
+with data cache disabled.
+
+To capture a timestamp in assembly code, the caller should use
+``pmf_calc_timestamp_addr`` macro (defined in ``pmf_asm_macros.S``) to
+calculate the address of where the timestamp would be stored. The
+caller should then read ``CNTPCT_EL0`` register to obtain the timestamp
+and store it at the determined address for later retrieval.
+
+Retrieving a timestamp
+~~~~~~~~~~~~~~~~~~~~~~
+
+From within TF-A, timestamps for individual CPUs can be retrieved using either
+``PMF_GET_TIMESTAMP_BY_MPIDR()`` or ``PMF_GET_TIMESTAMP_BY_INDEX()`` macros.
+These macros accept the CPU's MPIDR value, or its ordinal position
+respectively.
+
+From outside TF-A, timestamps for individual CPUs can be retrieved by calling
+into ``pmf_smc_handler()``.
+
+.. code:: c
+
+ Interface : pmf_smc_handler()
+ Argument : unsigned int smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, void *cookie,
+ void *handle, u_register_t flags
+ Return : uintptr_t
+
+ smc_fid: Holds the SMC identifier which is either `PMF_SMC_GET_TIMESTAMP_32`
+ when the caller of the SMC is running in AArch32 mode
+ or `PMF_SMC_GET_TIMESTAMP_64` when the caller is running in AArch64 mode.
+ x1: Timestamp identifier.
+ x2: The `mpidr` of the CPU for which the timestamp has to be retrieved.
+ This can be the `mpidr` of a different core to the one initiating
+ the SMC. In that case, service specific cache maintenance may be
+ required to ensure the updated copy of the timestamp is returned.
+ x3: A flags value that is either 0 or `PMF_CACHE_MAINT`. If
+ `PMF_CACHE_MAINT` is passed, then the PMF code will perform a
+ cache invalidate before reading the timestamp. This ensures
+ an updated copy is returned.
+
+The remaining arguments, ``x4``, ``cookie``, ``handle`` and ``flags`` are unused
+in this implementation.
+
+PMF code structure
+~~~~~~~~~~~~~~~~~~
+
+#. ``pmf_main.c`` consists of core functions that implement service registration,
+ initialization, storing, dumping and retrieving timestamps.
+
+#. ``pmf_smc.c`` contains the SMC handling for registered PMF services.
+
+#. ``pmf.h`` contains the public interface to Performance Measurement Framework.
+
+#. ``pmf_asm_macros.S`` consists of macros to facilitate capturing timestamps in
+ assembly code.
+
+#. ``pmf_helpers.h`` is an internal header used by ``pmf.h``.
+
+Armv8-A Architecture Extensions
+-------------------------------
+
+TF-A makes use of Armv8-A Architecture Extensions where applicable. This
+section lists the usage of Architecture Extensions, and build flags
+controlling them.
+
+In general, and unless individually mentioned, the build options
+``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` select the Architecture Extension to
+target when building TF-A. Subsequent Arm Architecture Extensions are backward
+compatible with previous versions.
+
+The build system only requires that ``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` have a
+valid numeric value. These build options only control whether or not
+Architecture Extension-specific code is included in the build. Otherwise, TF-A
+targets the base Armv8.0-A architecture; i.e. as if ``ARM_ARCH_MAJOR`` == 8
+and ``ARM_ARCH_MINOR`` == 0, which are also their respective default values.
+
+See also the *Summary of build options* in `User Guide`_.
+
+For details on the Architecture Extension and available features, please refer
+to the respective Architecture Extension Supplement.
+
+Armv8.1-A
+~~~~~~~~~
+
+This Architecture Extension is targeted when ``ARM_ARCH_MAJOR`` >= 8, or when
+``ARM_ARCH_MAJOR`` == 8 and ``ARM_ARCH_MINOR`` >= 1.
+
+- The Compare and Swap instruction is used to implement spinlocks. Otherwise,
+ the load-/store-exclusive instruction pair is used.
+
+Armv8.2-A
+~~~~~~~~~
+
+- The presence of ARMv8.2-TTCNP is detected at runtime. When it is present, the
+ Common not Private (TTBRn_ELx.CnP) bit is enabled to indicate that multiple
+ Processing Elements in the same Inner Shareable domain use the same
+ translation table entries for a given stage of translation for a particular
+ translation regime.
+
+Armv8.3-A
+~~~~~~~~~
+
+- Pointer authentication features of Armv8.3-A are unconditionally enabled in
+ the Non-secure world so that lower ELs are allowed to use them without
+ causing a trap to EL3.
+
+ In order to enable the Secure world to use it, ``CTX_INCLUDE_PAUTH_REGS``
+ must be set to 1. This will add all pointer authentication system registers
+ to the context that is saved when doing a world switch.
+
+ The TF-A itself has support for pointer authentication at runtime
+ that can be enabled by setting both options ``ENABLE_PAUTH`` and
+ ``CTX_INCLUDE_PAUTH_REGS`` to 1. This enables pointer authentication in BL1,
+ BL2, BL31, and the TSP if it is used.
+
+ These options are experimental features.
+
+ Note that Pointer Authentication is enabled for Non-secure world irrespective
+ of the value of these build flags if the CPU supports it.
+
+ If ``ARM_ARCH_MAJOR == 8`` and ``ARM_ARCH_MINOR >= 3`` the code footprint of
+ enabling PAuth is lower because the compiler will use the optimized
+ PAuth instructions rather than the backwards-compatible ones.
+
+Armv7-A
+~~~~~~~
+
+This Architecture Extension is targeted when ``ARM_ARCH_MAJOR`` == 7.
+
+There are several Armv7-A extensions available. Obviously the TrustZone
+extension is mandatory to support the TF-A bootloader and runtime services.
+
+Platform implementing an Armv7-A system can to define from its target
+Cortex-A architecture through ``ARM_CORTEX_A<X> = yes`` in their
+``platform.mk`` script. For example ``ARM_CORTEX_A15=yes`` for a
+Cortex-A15 target.
+
+Platform can also set ``ARM_WITH_NEON=yes`` to enable neon support.
+Note that using neon at runtime has constraints on non secure wolrd context.
+TF-A does not yet provide VFP context management.
+
+Directive ``ARM_CORTEX_A<x>`` and ``ARM_WITH_NEON`` are used to set
+the toolchain target architecture directive.
+
+Platform may choose to not define straight the toolchain target architecture
+directive by defining ``MARCH32_DIRECTIVE``.
+I.e:
+
+::
+
+ MARCH32_DIRECTIVE := -mach=armv7-a
+
+Code Structure
+--------------
+
+TF-A code is logically divided between the three boot loader stages mentioned
+in the previous sections. The code is also divided into the following
+categories (present as directories in the source code):
+
+- **Platform specific.** Choice of architecture specific code depends upon
+ the platform.
+- **Common code.** This is platform and architecture agnostic code.
+- **Library code.** This code comprises of functionality commonly used by all
+ other code. The PSCI implementation and other EL3 runtime frameworks reside
+ as Library components.
+- **Stage specific.** Code specific to a boot stage.
+- **Drivers.**
+- **Services.** EL3 runtime services (eg: SPD). Specific SPD services
+ reside in the ``services/spd`` directory (e.g. ``services/spd/tspd``).
+
+Each boot loader stage uses code from one or more of the above mentioned
+categories. Based upon the above, the code layout looks like this:
+
+::
+
+ Directory Used by BL1? Used by BL2? Used by BL31?
+ bl1 Yes No No
+ bl2 No Yes No
+ bl31 No No Yes
+ plat Yes Yes Yes
+ drivers Yes No Yes
+ common Yes Yes Yes
+ lib Yes Yes Yes
+ services No No Yes
+
+The build system provides a non configurable build option IMAGE_BLx for each
+boot loader stage (where x = BL stage). e.g. for BL1 , IMAGE_BL1 will be
+defined by the build system. This enables TF-A to compile certain code only
+for specific boot loader stages
+
+All assembler files have the ``.S`` extension. The linker source files for each
+boot stage have the extension ``.ld.S``. These are processed by GCC to create the
+linker scripts which have the extension ``.ld``.
+
+FDTs provide a description of the hardware platform and are used by the Linux
+kernel at boot time. These can be found in the ``fdts`` directory.
+
+References
+----------
+
+.. [#] `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D)`_
+.. [#] `Power State Coordination Interface PDD`_
+.. [#] `SMC Calling Convention PDD`_
+.. [#] `TF-A Interrupt Management Design guide`_.
+
+--------------
+
+*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _Reset Design: ./reset-design.rst
+.. _Porting Guide: ../getting_started/porting-guide.rst
+.. _Firmware Update: ./firmware-update.rst
+.. _PSCI PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _SMC calling convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
+.. _PSCI Library integration guide: ../getting_started/psci-lib-integration-guide.rst
+.. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
+.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _here: ../getting_started/psci-lib-integration-guide.rst
+.. _cpu-specific-build-macros.rst: ./cpu-specific-build-macros.rst
+.. _CPUBM: ./cpu-specific-build-macros.rst
+.. _Arm ARM: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.e/index.html
+.. _User Guide: ../getting_started/user-guide.rst
+.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
+.. _TF-A Interrupt Management Design guide: ./interrupt-framework-design.rst
+.. _Xlat_tables design: xlat-tables-lib-v2-design.rst
+.. _Exception Handling Framework: exception-handling.rst
+.. _ROMLIB Design: romlib-design.rst
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+
+.. |Image 1| image:: diagrams/rt-svc-descs-layout.png?raw=true
--- /dev/null
+System Design
+=============
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+ :numbered:
+
+ auth-framework
+ cpu-specific-build-macros
+ firmware-design
+ interrupt-framework-design
+ psci-pd-tree
+ reset-design
+ trusted-board-boot
--- /dev/null
+Trusted Firmware-A interrupt management design guide
+====================================================
+
+
+
+
+.. contents::
+
+This framework is responsible for managing interrupts routed to EL3. It also
+allows EL3 software to configure the interrupt routing behavior. Its main
+objective is to implement the following two requirements.
+
+#. It should be possible to route interrupts meant to be handled by secure
+ software (Secure interrupts) to EL3, when execution is in non-secure state
+ (normal world). The framework should then take care of handing control of
+ the interrupt to either software in EL3 or Secure-EL1 depending upon the
+ software configuration and the GIC implementation. This requirement ensures
+ that secure interrupts are under the control of the secure software with
+ respect to their delivery and handling without the possibility of
+ intervention from non-secure software.
+
+#. It should be possible to route interrupts meant to be handled by
+ non-secure software (Non-secure interrupts) to the last executed exception
+ level in the normal world when the execution is in secure world at
+ exception levels lower than EL3. This could be done with or without the
+ knowledge of software executing in Secure-EL1/Secure-EL0. The choice of
+ approach should be governed by the secure software. This requirement
+ ensures that non-secure software is able to execute in tandem with the
+ secure software without overriding it.
+
+Concepts
+--------
+
+Interrupt types
+~~~~~~~~~~~~~~~
+
+The framework categorises an interrupt to be one of the following depending upon
+the exception level(s) it is handled in.
+
+#. Secure EL1 interrupt. This type of interrupt can be routed to EL3 or
+ Secure-EL1 depending upon the security state of the current execution
+ context. It is always handled in Secure-EL1.
+
+#. Non-secure interrupt. This type of interrupt can be routed to EL3,
+ Secure-EL1, Non-secure EL1 or EL2 depending upon the security state of the
+ current execution context. It is always handled in either Non-secure EL1
+ or EL2.
+
+#. EL3 interrupt. This type of interrupt can be routed to EL3 or Secure-EL1
+ depending upon the security state of the current execution context. It is
+ always handled in EL3.
+
+The following constants define the various interrupt types in the framework
+implementation.
+
+::
+
+ #define INTR_TYPE_S_EL1 0
+ #define INTR_TYPE_EL3 1
+ #define INTR_TYPE_NS 2
+
+Routing model
+~~~~~~~~~~~~~
+
+A type of interrupt can be either generated as an FIQ or an IRQ. The target
+exception level of an interrupt type is configured through the FIQ and IRQ bits
+in the Secure Configuration Register at EL3 (``SCR_EL3.FIQ`` and ``SCR_EL3.IRQ``
+bits). When ``SCR_EL3.FIQ``\ =1, FIQs are routed to EL3. Otherwise they are routed
+to the First Exception Level (FEL) capable of handling interrupts. When
+``SCR_EL3.IRQ``\ =1, IRQs are routed to EL3. Otherwise they are routed to the
+FEL. This register is configured independently by EL3 software for each security
+state prior to entry into a lower exception level in that security state.
+
+A routing model for a type of interrupt (generated as FIQ or IRQ) is defined as
+its target exception level for each security state. It is represented by a
+single bit for each security state. A value of ``0`` means that the interrupt
+should be routed to the FEL. A value of ``1`` means that the interrupt should be
+routed to EL3. A routing model is applicable only when execution is not in EL3.
+
+The default routing model for an interrupt type is to route it to the FEL in
+either security state.
+
+Valid routing models
+~~~~~~~~~~~~~~~~~~~~
+
+The framework considers certain routing models for each type of interrupt to be
+incorrect as they conflict with the requirements mentioned in Section 1. The
+following sub-sections describe all the possible routing models and specify
+which ones are valid or invalid. EL3 interrupts are currently supported only
+for GIC version 3.0 (Arm GICv3) and only the Secure-EL1 and Non-secure interrupt
+types are supported for GIC version 2.0 (Arm GICv2) (see `Assumptions in
+Interrupt Management Framework`_). The terminology used in the following
+sub-sections is explained below.
+
+#. **CSS**. Current Security State. ``0`` when secure and ``1`` when non-secure
+
+#. **TEL3**. Target Exception Level 3. ``0`` when targeted to the FEL. ``1`` when
+ targeted to EL3.
+
+Secure-EL1 interrupts
+^^^^^^^^^^^^^^^^^^^^^
+
+#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in
+ secure state. This is a valid routing model as secure software is in
+ control of handling secure interrupts.
+
+#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in secure
+ state. This is a valid routing model as secure software in EL3 can
+ handover the interrupt to Secure-EL1 for handling.
+
+#. **CSS=1, TEL3=0**. Interrupt is routed to the FEL when execution is in
+ non-secure state. This is an invalid routing model as a secure interrupt
+ is not visible to the secure software which violates the motivation behind
+ the Arm Security Extensions.
+
+#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in
+ non-secure state. This is a valid routing model as secure software in EL3
+ can handover the interrupt to Secure-EL1 for handling.
+
+Non-secure interrupts
+^^^^^^^^^^^^^^^^^^^^^
+
+#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in
+ secure state. This allows the secure software to trap non-secure
+ interrupts, perform its book-keeping and hand the interrupt to the
+ non-secure software through EL3. This is a valid routing model as secure
+ software is in control of how its execution is preempted by non-secure
+ interrupts.
+
+#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in secure
+ state. This is a valid routing model as secure software in EL3 can save
+ the state of software in Secure-EL1/Secure-EL0 before handing the
+ interrupt to non-secure software. This model requires additional
+ coordination between Secure-EL1 and EL3 software to ensure that the
+ former's state is correctly saved by the latter.
+
+#. **CSS=1, TEL3=0**. Interrupt is routed to FEL when execution is in
+ non-secure state. This is a valid routing model as a non-secure interrupt
+ is handled by non-secure software.
+
+#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in
+ non-secure state. This is an invalid routing model as there is no valid
+ reason to route the interrupt to EL3 software and then hand it back to
+ non-secure software for handling.
+
+EL3 interrupts
+^^^^^^^^^^^^^^
+
+#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in
+ Secure-EL1/Secure-EL0. This is a valid routing model as secure software
+ in Secure-EL1/Secure-EL0 is in control of how its execution is preempted
+ by EL3 interrupt and can handover the interrupt to EL3 for handling.
+
+ However, when ``EL3_EXCEPTION_HANDLING`` is ``1``, this routing model is
+ invalid as EL3 interrupts are unconditionally routed to EL3, and EL3
+ interrupts will always preempt Secure EL1/EL0 execution. See `exception
+ handling`__ documentation.
+
+ .. __: exception-handling.rst#interrupt-handling
+
+#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in
+ Secure-EL1/Secure-EL0. This is a valid routing model as secure software
+ in EL3 can handle the interrupt.
+
+#. **CSS=1, TEL3=0**. Interrupt is routed to the FEL when execution is in
+ non-secure state. This is an invalid routing model as a secure interrupt
+ is not visible to the secure software which violates the motivation behind
+ the Arm Security Extensions.
+
+#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in
+ non-secure state. This is a valid routing model as secure software in EL3
+ can handle the interrupt.
+
+Mapping of interrupt type to signal
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The framework is meant to work with any interrupt controller implemented by a
+platform. A interrupt controller could generate a type of interrupt as either an
+FIQ or IRQ signal to the CPU depending upon the current security state. The
+mapping between the type and signal is known only to the platform. The framework
+uses this information to determine whether the IRQ or the FIQ bit should be
+programmed in ``SCR_EL3`` while applying the routing model for a type of
+interrupt. The platform provides this information through the
+``plat_interrupt_type_to_line()`` API (described in the
+`Porting Guide`_). For example, on the FVP port when the platform uses an Arm GICv2
+interrupt controller, Secure-EL1 interrupts are signaled through the FIQ signal
+while Non-secure interrupts are signaled through the IRQ signal. This applies
+when execution is in either security state.
+
+Effect of mapping of several interrupt types to one signal
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+It should be noted that if more than one interrupt type maps to a single
+interrupt signal, and if any one of the interrupt type sets **TEL3=1** for a
+particular security state, then interrupt signal will be routed to EL3 when in
+that security state. This means that all the other interrupt types using the
+same interrupt signal will be forced to the same routing model. This should be
+borne in mind when choosing the routing model for an interrupt type.
+
+For example, in Arm GICv3, when the execution context is Secure-EL1/
+Secure-EL0, both the EL3 and the non secure interrupt types map to the FIQ
+signal. So if either one of the interrupt type sets the routing model so
+that **TEL3=1** when **CSS=0**, the FIQ bit in ``SCR_EL3`` will be programmed to
+route the FIQ signal to EL3 when executing in Secure-EL1/Secure-EL0, thereby
+effectively routing the other interrupt type also to EL3.
+
+Assumptions in Interrupt Management Framework
+---------------------------------------------
+
+The framework makes the following assumptions to simplify its implementation.
+
+#. Although the framework has support for 2 types of secure interrupts (EL3
+ and Secure-EL1 interrupt), only interrupt controller architectures
+ like Arm GICv3 has architectural support for EL3 interrupts in the form of
+ Group 0 interrupts. In Arm GICv2, all secure interrupts are assumed to be
+ handled in Secure-EL1. They can be delivered to Secure-EL1 via EL3 but they
+ cannot be handled in EL3.
+
+#. Interrupt exceptions (``PSTATE.I`` and ``F`` bits) are masked during execution
+ in EL3.
+
+#. Interrupt management: the following sections describe how interrupts are
+ managed by the interrupt handling framework. This entails:
+
+ #. Providing an interface to allow registration of a handler and
+ specification of the routing model for a type of interrupt.
+
+ #. Implementing support to hand control of an interrupt type to its
+ registered handler when the interrupt is generated.
+
+Both aspects of interrupt management involve various components in the secure
+software stack spanning from EL3 to Secure-EL1. These components are described
+in the section `Software components`_. The framework stores information
+associated with each type of interrupt in the following data structure.
+
+.. code:: c
+
+ typedef struct intr_type_desc {
+ interrupt_type_handler_t handler;
+ uint32_t flags;
+ uint32_t scr_el3[2];
+ } intr_type_desc_t;
+
+The ``flags`` field stores the routing model for the interrupt type in
+bits[1:0]. Bit[0] stores the routing model when execution is in the secure
+state. Bit[1] stores the routing model when execution is in the non-secure
+state. As mentioned in Section `Routing model`_, a value of ``0`` implies that
+the interrupt should be targeted to the FEL. A value of ``1`` implies that it
+should be targeted to EL3. The remaining bits are reserved and SBZ. The helper
+macro ``set_interrupt_rm_flag()`` should be used to set the bits in the
+``flags`` parameter.
+
+The ``scr_el3[2]`` field also stores the routing model but as a mapping of the
+model in the ``flags`` field to the corresponding bit in the ``SCR_EL3`` for each
+security state.
+
+The framework also depends upon the platform port to configure the interrupt
+controller to distinguish between secure and non-secure interrupts. The platform
+is expected to be aware of the secure devices present in the system and their
+associated interrupt numbers. It should configure the interrupt controller to
+enable the secure interrupts, ensure that their priority is always higher than
+the non-secure interrupts and target them to the primary CPU. It should also
+export the interface described in the `Porting Guide`_ to enable
+handling of interrupts.
+
+In the remainder of this document, for the sake of simplicity a Arm GICv2 system
+is considered and it is assumed that the FIQ signal is used to generate Secure-EL1
+interrupts and the IRQ signal is used to generate non-secure interrupts in either
+security state. EL3 interrupts are not considered.
+
+Software components
+-------------------
+
+Roles and responsibilities for interrupt management are sub-divided between the
+following components of software running in EL3 and Secure-EL1. Each component is
+briefly described below.
+
+#. EL3 Runtime Firmware. This component is common to all ports of TF-A.
+
+#. Secure Payload Dispatcher (SPD) service. This service interfaces with the
+ Secure Payload (SP) software which runs in Secure-EL1/Secure-EL0 and is
+ responsible for switching execution between secure and non-secure states.
+ A switch is triggered by a Secure Monitor Call and it uses the APIs
+ exported by the Context management library to implement this functionality.
+ Switching execution between the two security states is a requirement for
+ interrupt management as well. This results in a significant dependency on
+ the SPD service. TF-A implements an example Test Secure Payload Dispatcher
+ (TSPD) service.
+
+ An SPD service plugs into the EL3 runtime firmware and could be common to
+ some ports of TF-A.
+
+#. Secure Payload (SP). On a production system, the Secure Payload corresponds
+ to a Secure OS which runs in Secure-EL1/Secure-EL0. It interfaces with the
+ SPD service to manage communication with non-secure software. TF-A
+ implements an example secure payload called Test Secure Payload (TSP)
+ which runs only in Secure-EL1.
+
+ A Secure payload implementation could be common to some ports of TF-A,
+ just like the SPD service.
+
+Interrupt registration
+----------------------
+
+This section describes in detail the role of each software component (see
+`Software components`_) during the registration of a handler for an interrupt
+type.
+
+EL3 runtime firmware
+~~~~~~~~~~~~~~~~~~~~
+
+This component declares the following prototype for a handler of an interrupt type.
+
+.. code:: c
+
+ typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,
+ uint32_t flags,
+ void *handle,
+ void *cookie);
+
+The ``id`` is parameter is reserved and could be used in the future for passing
+the interrupt id of the highest pending interrupt only if there is a foolproof
+way of determining the id. Currently it contains ``INTR_ID_UNAVAILABLE``.
+
+The ``flags`` parameter contains miscellaneous information as follows.
+
+#. Security state, bit[0]. This bit indicates the security state of the lower
+ exception level when the interrupt was generated. A value of ``1`` means
+ that it was in the non-secure state. A value of ``0`` indicates that it was
+ in the secure state. This bit can be used by the handler to ensure that
+ interrupt was generated and routed as per the routing model specified
+ during registration.
+
+#. Reserved, bits[31:1]. The remaining bits are reserved for future use.
+
+The ``handle`` parameter points to the ``cpu_context`` structure of the current CPU
+for the security state specified in the ``flags`` parameter.
+
+Once the handler routine completes, execution will return to either the secure
+or non-secure state. The handler routine must return a pointer to
+``cpu_context`` structure of the current CPU for the target security state. On
+AArch64, this return value is currently ignored by the caller as the
+appropriate ``cpu_context`` to be used is expected to be set by the handler
+via the context management library APIs.
+A portable interrupt handler implementation must set the target context both in
+the structure pointed to by the returned pointer and via the context management
+library APIs. The handler should treat all error conditions as critical errors
+and take appropriate action within its implementation e.g. use assertion
+failures.
+
+The runtime firmware provides the following API for registering a handler for a
+particular type of interrupt. A Secure Payload Dispatcher service should use
+this API to register a handler for Secure-EL1 and optionally for non-secure
+interrupts. This API also requires the caller to specify the routing model for
+the type of interrupt.
+
+.. code:: c
+
+ int32_t register_interrupt_type_handler(uint32_t type,
+ interrupt_type_handler handler,
+ uint64_t flags);
+
+The ``type`` parameter can be one of the three interrupt types listed above i.e.
+``INTR_TYPE_S_EL1``, ``INTR_TYPE_NS`` & ``INTR_TYPE_EL3``. The ``flags`` parameter
+is as described in Section 2.
+
+The function will return ``0`` upon a successful registration. It will return
+``-EALREADY`` in case a handler for the interrupt type has already been
+registered. If the ``type`` is unrecognised or the ``flags`` or the ``handler`` are
+invalid it will return ``-EINVAL``.
+
+Interrupt routing is governed by the configuration of the ``SCR_EL3.FIQ/IRQ`` bits
+prior to entry into a lower exception level in either security state. The
+context management library maintains a copy of the ``SCR_EL3`` system register for
+each security state in the ``cpu_context`` structure of each CPU. It exports the
+following APIs to let EL3 Runtime Firmware program and retrieve the routing
+model for each security state for the current CPU. The value of ``SCR_EL3`` stored
+in the ``cpu_context`` is used by the ``el3_exit()`` function to program the
+``SCR_EL3`` register prior to returning from the EL3 exception level.
+
+.. code:: c
+
+ uint32_t cm_get_scr_el3(uint32_t security_state);
+ void cm_write_scr_el3_bit(uint32_t security_state,
+ uint32_t bit_pos,
+ uint32_t value);
+
+``cm_get_scr_el3()`` returns the value of the ``SCR_EL3`` register for the specified
+security state of the current CPU. ``cm_write_scr_el3()`` writes a ``0`` or ``1`` to
+the bit specified by ``bit_pos``. ``register_interrupt_type_handler()`` invokes
+``set_routing_model()`` API which programs the ``SCR_EL3`` according to the routing
+model using the ``cm_get_scr_el3()`` and ``cm_write_scr_el3_bit()`` APIs.
+
+It is worth noting that in the current implementation of the framework, the EL3
+runtime firmware is responsible for programming the routing model. The SPD is
+responsible for ensuring that the routing model has been adhered to upon
+receiving an interrupt.
+
+.. _spd-int-registration:
+
+Secure payload dispatcher
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A SPD service is responsible for determining and maintaining the interrupt
+routing model supported by itself and the Secure Payload. It is also responsible
+for ferrying interrupts between secure and non-secure software depending upon
+the routing model. It could determine the routing model at build time or at
+runtime. It must use this information to register a handler for each interrupt
+type using the ``register_interrupt_type_handler()`` API in EL3 runtime firmware.
+
+If the routing model is not known to the SPD service at build time, then it must
+be provided by the SP as the result of its initialisation. The SPD should
+program the routing model only after SP initialisation has completed e.g. in the
+SPD initialisation function pointed to by the ``bl32_init`` variable.
+
+The SPD should determine the mechanism to pass control to the Secure Payload
+after receiving an interrupt from the EL3 runtime firmware. This information
+could either be provided to the SPD service at build time or by the SP at
+runtime.
+
+Test secure payload dispatcher behavior
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Note:** where this document discusses ``TSP_NS_INTR_ASYNC_PREEMPT`` as being
+``1``, the same results also apply when ``EL3_EXCEPTION_HANDLING`` is ``1``.
+
+The TSPD only handles Secure-EL1 interrupts and is provided with the following
+routing model at build time.
+
+- Secure-EL1 interrupts are routed to EL3 when execution is in non-secure
+ state and are routed to the FEL when execution is in the secure state
+ i.e **CSS=0, TEL3=0** & **CSS=1, TEL3=1** for Secure-EL1 interrupts
+
+- When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is zero, the default routing
+ model is used for non-secure interrupts. They are routed to the FEL in
+ either security state i.e **CSS=0, TEL3=0** & **CSS=1, TEL3=0** for
+ Non-secure interrupts.
+
+- When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is defined to 1, then the
+ non secure interrupts are routed to EL3 when execution is in secure state
+ i.e **CSS=0, TEL3=1** for non-secure interrupts. This effectively preempts
+ Secure-EL1. The default routing model is used for non secure interrupts in
+ non-secure state. i.e **CSS=1, TEL3=0**.
+
+It performs the following actions in the ``tspd_init()`` function to fulfill the
+requirements mentioned earlier.
+
+#. It passes control to the Test Secure Payload to perform its
+ initialisation. The TSP provides the address of the vector table
+ ``tsp_vectors`` in the SP which also includes the handler for Secure-EL1
+ interrupts in the ``sel1_intr_entry`` field. The TSPD passes control to the TSP at
+ this address when it receives a Secure-EL1 interrupt.
+
+ The handover agreement between the TSP and the TSPD requires that the TSPD
+ masks all interrupts (``PSTATE.DAIF`` bits) when it calls
+ ``tsp_sel1_intr_entry()``. The TSP has to preserve the callee saved general
+ purpose, SP_EL1/Secure-EL0, LR, VFP and system registers. It can use
+ ``x0-x18`` to enable its C runtime.
+
+#. The TSPD implements a handler function for Secure-EL1 interrupts. This
+ function is registered with the EL3 runtime firmware using the
+ ``register_interrupt_type_handler()`` API as follows
+
+ .. code:: c
+
+ /* Forward declaration */
+ interrupt_type_handler tspd_secure_el1_interrupt_handler;
+ int32_t rc, flags = 0;
+ set_interrupt_rm_flag(flags, NON_SECURE);
+ rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
+ tspd_secure_el1_interrupt_handler,
+ flags);
+ if (rc)
+ panic();
+
+#. When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is defined to 1, the TSPD
+ implements a handler function for non-secure interrupts. This function is
+ registered with the EL3 runtime firmware using the
+ ``register_interrupt_type_handler()`` API as follows
+
+ .. code:: c
+
+ /* Forward declaration */
+ interrupt_type_handler tspd_ns_interrupt_handler;
+ int32_t rc, flags = 0;
+ set_interrupt_rm_flag(flags, SECURE);
+ rc = register_interrupt_type_handler(INTR_TYPE_NS,
+ tspd_ns_interrupt_handler,
+ flags);
+ if (rc)
+ panic();
+
+.. _sp-int-registration:
+
+Secure payload
+~~~~~~~~~~~~~~
+
+A Secure Payload must implement an interrupt handling framework at Secure-EL1
+(Secure-EL1 IHF) to support its chosen interrupt routing model. Secure payload
+execution will alternate between the below cases.
+
+#. In the code where IRQ, FIQ or both interrupts are enabled, if an interrupt
+ type is targeted to the FEL, then it will be routed to the Secure-EL1
+ exception vector table. This is defined as the **asynchronous mode** of
+ handling interrupts. This mode applies to both Secure-EL1 and non-secure
+ interrupts.
+
+#. In the code where both interrupts are disabled, if an interrupt type is
+ targeted to the FEL, then execution will eventually migrate to the
+ non-secure state. Any non-secure interrupts will be handled as described
+ in the routing model where **CSS=1 and TEL3=0**. Secure-EL1 interrupts
+ will be routed to EL3 (as per the routing model where **CSS=1 and
+ TEL3=1**) where the SPD service will hand them to the SP. This is defined
+ as the **synchronous mode** of handling interrupts.
+
+The interrupt handling framework implemented by the SP should support one or
+both these interrupt handling models depending upon the chosen routing model.
+
+The following list briefly describes how the choice of a valid routing model
+(see `Valid routing models`_) effects the implementation of the Secure-EL1
+IHF. If the choice of the interrupt routing model is not known to the SPD
+service at compile time, then the SP should pass this information to the SPD
+service at runtime during its initialisation phase.
+
+As mentioned earlier, an Arm GICv2 system is considered and it is assumed that
+the FIQ signal is used to generate Secure-EL1 interrupts and the IRQ signal
+is used to generate non-secure interrupts in either security state.
+
+Secure payload IHF design w.r.t secure-EL1 interrupts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+#. **CSS=0, TEL3=0**. If ``PSTATE.F=0``, Secure-EL1 interrupts will be
+ triggered at one of the Secure-EL1 FIQ exception vectors. The Secure-EL1
+ IHF should implement support for handling FIQ interrupts asynchronously.
+
+ If ``PSTATE.F=1`` then Secure-EL1 interrupts will be handled as per the
+ synchronous interrupt handling model. The SP could implement this scenario
+ by exporting a separate entrypoint for Secure-EL1 interrupts to the SPD
+ service during the registration phase. The SPD service would also need to
+ know the state of the system, general purpose and the ``PSTATE`` registers
+ in which it should arrange to return execution to the SP. The SP should
+ provide this information in an implementation defined way during the
+ registration phase if it is not known to the SPD service at build time.
+
+#. **CSS=1, TEL3=1**. Interrupts are routed to EL3 when execution is in
+ non-secure state. They should be handled through the synchronous interrupt
+ handling model as described in 1. above.
+
+#. **CSS=0, TEL3=1**. Secure-EL1 interrupts are routed to EL3 when execution
+ is in secure state. They will not be visible to the SP. The ``PSTATE.F`` bit
+ in Secure-EL1/Secure-EL0 will not mask FIQs. The EL3 runtime firmware will
+ call the handler registered by the SPD service for Secure-EL1 interrupts.
+ Secure-EL1 IHF should then handle all Secure-EL1 interrupt through the
+ synchronous interrupt handling model described in 1. above.
+
+Secure payload IHF design w.r.t non-secure interrupts
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+#. **CSS=0, TEL3=0**. If ``PSTATE.I=0``, non-secure interrupts will be
+ triggered at one of the Secure-EL1 IRQ exception vectors . The Secure-EL1
+ IHF should co-ordinate with the SPD service to transfer execution to the
+ non-secure state where the interrupt should be handled e.g the SP could
+ allocate a function identifier to issue a SMC64 or SMC32 to the SPD
+ service which indicates that the SP execution has been preempted by a
+ non-secure interrupt. If this function identifier is not known to the SPD
+ service at compile time then the SP could provide it during the
+ registration phase.
+
+ If ``PSTATE.I=1`` then the non-secure interrupt will pend until execution
+ resumes in the non-secure state.
+
+#. **CSS=0, TEL3=1**. Non-secure interrupts are routed to EL3. They will not
+ be visible to the SP. The ``PSTATE.I`` bit in Secure-EL1/Secure-EL0 will
+ have not effect. The SPD service should register a non-secure interrupt
+ handler which should save the SP state correctly and resume execution in
+ the non-secure state where the interrupt will be handled. The Secure-EL1
+ IHF does not need to take any action.
+
+#. **CSS=1, TEL3=0**. Non-secure interrupts are handled in the FEL in
+ non-secure state (EL1/EL2) and are not visible to the SP. This routing
+ model does not affect the SP behavior.
+
+A Secure Payload must also ensure that all Secure-EL1 interrupts are correctly
+configured at the interrupt controller by the platform port of the EL3 runtime
+firmware. It should configure any additional Secure-EL1 interrupts which the EL3
+runtime firmware is not aware of through its platform port.
+
+Test secure payload behavior
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The routing model for Secure-EL1 and non-secure interrupts chosen by the TSP is
+described in Section `Secure Payload Dispatcher`__. It is known to the TSPD
+service at build time.
+
+.. __: #spd-int-registration
+
+The TSP implements an entrypoint (``tsp_sel1_intr_entry()``) for handling Secure-EL1
+interrupts taken in non-secure state and routed through the TSPD service
+(synchronous handling model). It passes the reference to this entrypoint via
+``tsp_vectors`` to the TSPD service.
+
+The TSP also replaces the default exception vector table referenced through the
+``early_exceptions`` variable, with a vector table capable of handling FIQ and IRQ
+exceptions taken at the same (Secure-EL1) exception level. This table is
+referenced through the ``tsp_exceptions`` variable and programmed into the
+VBAR_EL1. It caters for the asynchronous handling model.
+
+The TSP also programs the Secure Physical Timer in the Arm Generic Timer block
+to raise a periodic interrupt (every half a second) for the purpose of testing
+interrupt management across all the software components listed in `Software
+components`_.
+
+Interrupt handling
+------------------
+
+This section describes in detail the role of each software component (see
+Section `Software components`_) in handling an interrupt of a particular type.
+
+EL3 runtime firmware
+~~~~~~~~~~~~~~~~~~~~
+
+The EL3 runtime firmware populates the IRQ and FIQ exception vectors referenced
+by the ``runtime_exceptions`` variable as follows.
+
+#. IRQ and FIQ exceptions taken from the current exception level with
+ ``SP_EL0`` or ``SP_EL3`` are reported as irrecoverable error conditions. As
+ mentioned earlier, EL3 runtime firmware always executes with the
+ ``PSTATE.I`` and ``PSTATE.F`` bits set.
+
+#. The following text describes how the IRQ and FIQ exceptions taken from a
+ lower exception level using AArch64 or AArch32 are handled.
+
+When an interrupt is generated, the vector for each interrupt type is
+responsible for:
+
+#. Saving the entire general purpose register context (x0-x30) immediately
+ upon exception entry. The registers are saved in the per-cpu ``cpu_context``
+ data structure referenced by the ``SP_EL3``\ register.
+
+#. Saving the ``ELR_EL3``, ``SP_EL0`` and ``SPSR_EL3`` system registers in the
+ per-cpu ``cpu_context`` data structure referenced by the ``SP_EL3`` register.
+
+#. Switching to the C runtime stack by restoring the ``CTX_RUNTIME_SP`` value
+ from the per-cpu ``cpu_context`` data structure in ``SP_EL0`` and
+ executing the ``msr spsel, #0`` instruction.
+
+#. Determining the type of interrupt. Secure-EL1 interrupts will be signaled
+ at the FIQ vector. Non-secure interrupts will be signaled at the IRQ
+ vector. The platform should implement the following API to determine the
+ type of the pending interrupt.
+
+ .. code:: c
+
+ uint32_t plat_ic_get_interrupt_type(void);
+
+ It should return either ``INTR_TYPE_S_EL1`` or ``INTR_TYPE_NS``.
+
+#. Determining the handler for the type of interrupt that has been generated.
+ The following API has been added for this purpose.
+
+ .. code:: c
+
+ interrupt_type_handler get_interrupt_type_handler(uint32_t interrupt_type);
+
+ It returns the reference to the registered handler for this interrupt
+ type. The ``handler`` is retrieved from the ``intr_type_desc_t`` structure as
+ described in Section 2. ``NULL`` is returned if no handler has been
+ registered for this type of interrupt. This scenario is reported as an
+ irrecoverable error condition.
+
+#. Calling the registered handler function for the interrupt type generated.
+ The ``id`` parameter is set to ``INTR_ID_UNAVAILABLE`` currently. The id along
+ with the current security state and a reference to the ``cpu_context_t``
+ structure for the current security state are passed to the handler function
+ as its arguments.
+
+ The handler function returns a reference to the per-cpu ``cpu_context_t``
+ structure for the target security state.
+
+#. Calling ``el3_exit()`` to return from EL3 into a lower exception level in
+ the security state determined by the handler routine. The ``el3_exit()``
+ function is responsible for restoring the register context from the
+ ``cpu_context_t`` data structure for the target security state.
+
+Secure payload dispatcher
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Interrupt entry
+^^^^^^^^^^^^^^^
+
+The SPD service begins handling an interrupt when the EL3 runtime firmware calls
+the handler function for that type of interrupt. The SPD service is responsible
+for the following:
+
+#. Validating the interrupt. This involves ensuring that the interrupt was
+ generated according to the interrupt routing model specified by the SPD
+ service during registration. It should use the security state of the
+ exception level (passed in the ``flags`` parameter of the handler) where
+ the interrupt was taken from to determine this. If the interrupt is not
+ recognised then the handler should treat it as an irrecoverable error
+ condition.
+
+ An SPD service can register a handler for Secure-EL1 and/or Non-secure
+ interrupts. A non-secure interrupt should never be routed to EL3 from
+ from non-secure state. Also if a routing model is chosen where Secure-EL1
+ interrupts are routed to S-EL1 when execution is in Secure state, then a
+ S-EL1 interrupt should never be routed to EL3 from secure state. The handler
+ could use the security state flag to check this.
+
+#. Determining whether a context switch is required. This depends upon the
+ routing model and interrupt type. For non secure and S-EL1 interrupt,
+ if the security state of the execution context where the interrupt was
+ generated is not the same as the security state required for handling
+ the interrupt, a context switch is required. The following 2 cases
+ require a context switch from secure to non-secure or vice-versa:
+
+ #. A Secure-EL1 interrupt taken from the non-secure state should be
+ routed to the Secure Payload.
+
+ #. A non-secure interrupt taken from the secure state should be routed
+ to the last known non-secure exception level.
+
+ The SPD service must save the system register context of the current
+ security state. It must then restore the system register context of the
+ target security state. It should use the ``cm_set_next_eret_context()`` API
+ to ensure that the next ``cpu_context`` to be restored is of the target
+ security state.
+
+ If the target state is secure then execution should be handed to the SP as
+ per the synchronous interrupt handling model it implements. A Secure-EL1
+ interrupt can be routed to EL3 while execution is in the SP. This implies
+ that SP execution can be preempted while handling an interrupt by a
+ another higher priority Secure-EL1 interrupt or a EL3 interrupt. The SPD
+ service should be able to handle this preemption or manage secure interrupt
+ priorities before handing control to the SP.
+
+#. Setting the return value of the handler to the per-cpu ``cpu_context`` if
+ the interrupt has been successfully validated and ready to be handled at a
+ lower exception level.
+
+The routing model allows non-secure interrupts to interrupt Secure-EL1 when in
+secure state if it has been configured to do so. The SPD service and the SP
+should implement a mechanism for routing these interrupts to the last known
+exception level in the non-secure state. The former should save the SP context,
+restore the non-secure context and arrange for entry into the non-secure state
+so that the interrupt can be handled.
+
+Interrupt exit
+^^^^^^^^^^^^^^
+
+When the Secure Payload has finished handling a Secure-EL1 interrupt, it could
+return control back to the SPD service through a SMC32 or SMC64. The SPD service
+should handle this secure monitor call so that execution resumes in the
+exception level and the security state from where the Secure-EL1 interrupt was
+originally taken.
+
+Test secure payload dispatcher Secure-EL1 interrupt handling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The example TSPD service registers a handler for Secure-EL1 interrupts taken
+from the non-secure state. During execution in S-EL1, the TSPD expects that the
+Secure-EL1 interrupts are handled in S-EL1 by TSP. Its handler
+``tspd_secure_el1_interrupt_handler()`` expects only to be invoked for Secure-EL1
+originating from the non-secure state. It takes the following actions upon being
+invoked.
+
+#. It uses the security state provided in the ``flags`` parameter to ensure
+ that the secure interrupt originated from the non-secure state. It asserts
+ if this is not the case.
+
+#. It saves the system register context for the non-secure state by calling
+ ``cm_el1_sysregs_context_save(NON_SECURE);``.
+
+#. It sets the ``ELR_EL3`` system register to ``tsp_sel1_intr_entry`` and sets the
+ ``SPSR_EL3.DAIF`` bits in the secure CPU context. It sets ``x0`` to
+ ``TSP_HANDLE_SEL1_INTR_AND_RETURN``. If the TSP was preempted earlier by a non
+ secure interrupt during ``yielding`` SMC processing, save the registers that
+ will be trashed, which is the ``ELR_EL3`` and ``SPSR_EL3``, in order to be able
+ to re-enter TSP for Secure-EL1 interrupt processing. It does not need to
+ save any other secure context since the TSP is expected to preserve it
+ (see section `Test secure payload dispatcher behavior`_).
+
+#. It restores the system register context for the secure state by calling
+ ``cm_el1_sysregs_context_restore(SECURE);``.
+
+#. It ensures that the secure CPU context is used to program the next
+ exception return from EL3 by calling ``cm_set_next_eret_context(SECURE);``.
+
+#. It returns the per-cpu ``cpu_context`` to indicate that the interrupt can
+ now be handled by the SP. ``x1`` is written with the value of ``elr_el3``
+ register for the non-secure state. This information is used by the SP for
+ debugging purposes.
+
+The figure below describes how the interrupt handling is implemented by the TSPD
+when a Secure-EL1 interrupt is generated when execution is in the non-secure
+state.
+
+|Image 1|
+
+The TSP issues an SMC with ``TSP_HANDLED_S_EL1_INTR`` as the function identifier to
+signal completion of interrupt handling.
+
+The TSPD service takes the following actions in ``tspd_smc_handler()`` function
+upon receiving an SMC with ``TSP_HANDLED_S_EL1_INTR`` as the function identifier:
+
+#. It ensures that the call originated from the secure state otherwise
+ execution returns to the non-secure state with ``SMC_UNK`` in ``x0``.
+
+#. It restores the saved ``ELR_EL3`` and ``SPSR_EL3`` system registers back to
+ the secure CPU context (see step 3 above) in case the TSP had been preempted
+ by a non secure interrupt earlier.
+
+#. It restores the system register context for the non-secure state by
+ calling ``cm_el1_sysregs_context_restore(NON_SECURE)``.
+
+#. It ensures that the non-secure CPU context is used to program the next
+ exception return from EL3 by calling ``cm_set_next_eret_context(NON_SECURE)``.
+
+#. ``tspd_smc_handler()`` returns a reference to the non-secure ``cpu_context``
+ as the return value.
+
+Test secure payload dispatcher non-secure interrupt handling
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The TSP in Secure-EL1 can be preempted by a non-secure interrupt during
+``yielding`` SMC processing or by a higher priority EL3 interrupt during
+Secure-EL1 interrupt processing. When ``EL3_EXCEPTION_HANDLING`` is ``0``, only
+non-secure interrupts can cause preemption of TSP since there are no EL3
+interrupts in the system. With ``EL3_EXCEPTION_HANDLING=1`` however, any EL3
+interrupt may preempt Secure execution.
+
+It should be noted that while TSP is preempted, the TSPD only allows entry into
+the TSP either for Secure-EL1 interrupt handling or for resuming the preempted
+``yielding`` SMC in response to the ``TSP_FID_RESUME`` SMC from the normal world.
+(See Section `Implication of preempted SMC on Non-Secure Software`_).
+
+The non-secure interrupt triggered in Secure-EL1 during ``yielding`` SMC
+processing can be routed to either EL3 or Secure-EL1 and is controlled by build
+option ``TSP_NS_INTR_ASYNC_PREEMPT`` (see Section `Test secure payload
+dispatcher behavior`_). If the build option is set, the TSPD will set the
+routing model for the non-secure interrupt to be routed to EL3 from secure state
+i.e. **TEL3=1, CSS=0** and registers ``tspd_ns_interrupt_handler()`` as the
+non-secure interrupt handler. The ``tspd_ns_interrupt_handler()`` on being
+invoked ensures that the interrupt originated from the secure state and disables
+routing of non-secure interrupts from secure state to EL3. This is to prevent
+further preemption (by a non-secure interrupt) when TSP is reentered for
+handling Secure-EL1 interrupts that triggered while execution was in the normal
+world. The ``tspd_ns_interrupt_handler()`` then invokes
+``tspd_handle_sp_preemption()`` for further handling.
+
+If the ``TSP_NS_INTR_ASYNC_PREEMPT`` build option is zero (default), the default
+routing model for non-secure interrupt in secure state is in effect
+i.e. **TEL3=0, CSS=0**. During ``yielding`` SMC processing, the IRQ
+exceptions are unmasked i.e. ``PSTATE.I=0``, and a non-secure interrupt will
+trigger at Secure-EL1 IRQ exception vector. The TSP saves the general purpose
+register context and issues an SMC with ``TSP_PREEMPTED`` as the function
+identifier to signal preemption of TSP. The TSPD SMC handler,
+``tspd_smc_handler()``, ensures that the SMC call originated from the
+secure state otherwise execution returns to the non-secure state with
+``SMC_UNK`` in ``x0``. It then invokes ``tspd_handle_sp_preemption()`` for
+further handling.
+
+The ``tspd_handle_sp_preemption()`` takes the following actions upon being
+invoked:
+
+#. It saves the system register context for the secure state by calling
+ ``cm_el1_sysregs_context_save(SECURE)``.
+
+#. It restores the system register context for the non-secure state by
+ calling ``cm_el1_sysregs_context_restore(NON_SECURE)``.
+
+#. It ensures that the non-secure CPU context is used to program the next
+ exception return from EL3 by calling ``cm_set_next_eret_context(NON_SECURE)``.
+
+#. ``SMC_PREEMPTED`` is set in x0 and return to non secure state after
+ restoring non secure context.
+
+The Normal World is expected to resume the TSP after the ``yielding`` SMC
+preemption by issuing an SMC with ``TSP_FID_RESUME`` as the function identifier
+(see section `Implication of preempted SMC on Non-Secure Software`_). The TSPD
+service takes the following actions in ``tspd_smc_handler()`` function upon
+receiving this SMC:
+
+#. It ensures that the call originated from the non secure state. An
+ assertion is raised otherwise.
+
+#. Checks whether the TSP needs a resume i.e check if it was preempted. It
+ then saves the system register context for the non-secure state by calling
+ ``cm_el1_sysregs_context_save(NON_SECURE)``.
+
+#. Restores the secure context by calling
+ ``cm_el1_sysregs_context_restore(SECURE)``
+
+#. It ensures that the secure CPU context is used to program the next
+ exception return from EL3 by calling ``cm_set_next_eret_context(SECURE)``.
+
+#. ``tspd_smc_handler()`` returns a reference to the secure ``cpu_context`` as the
+ return value.
+
+The figure below describes how the TSP/TSPD handle a non-secure interrupt when
+it is generated during execution in the TSP with ``PSTATE.I`` = 0 when the
+``TSP_NS_INTR_ASYNC_PREEMPT`` build flag is 0.
+
+|Image 2|
+
+Secure payload
+~~~~~~~~~~~~~~
+
+The SP should implement one or both of the synchronous and asynchronous
+interrupt handling models depending upon the interrupt routing model it has
+chosen (as described in section `Secure Payload`__).
+
+.. __: #sp-int-registration
+
+In the synchronous model, it should begin handling a Secure-EL1 interrupt after
+receiving control from the SPD service at an entrypoint agreed upon during build
+time or during the registration phase. Before handling the interrupt, the SP
+should save any Secure-EL1 system register context which is needed for resuming
+normal execution in the SP later e.g. ``SPSR_EL1``, ``ELR_EL1``. After handling
+the interrupt, the SP could return control back to the exception level and
+security state where the interrupt was originally taken from. The SP should use
+an SMC32 or SMC64 to ask the SPD service to do this.
+
+In the asynchronous model, the Secure Payload is responsible for handling
+non-secure and Secure-EL1 interrupts at the IRQ and FIQ vectors in its exception
+vector table when ``PSTATE.I`` and ``PSTATE.F`` bits are 0. As described earlier,
+when a non-secure interrupt is generated, the SP should coordinate with the SPD
+service to pass control back to the non-secure state in the last known exception
+level. This will allow the non-secure interrupt to be handled in the non-secure
+state.
+
+Test secure payload behavior
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The TSPD hands control of a Secure-EL1 interrupt to the TSP at the
+``tsp_sel1_intr_entry()``. The TSP handles the interrupt while ensuring that the
+handover agreement described in Section `Test secure payload dispatcher
+behavior`_ is maintained. It updates some statistics by calling
+``tsp_update_sync_sel1_intr_stats()``. It then calls
+``tsp_common_int_handler()`` which.
+
+#. Checks whether the interrupt is the secure physical timer interrupt. It
+ uses the platform API ``plat_ic_get_pending_interrupt_id()`` to get the
+ interrupt number. If it is not the secure physical timer interrupt, then
+ that means that a higher priority interrupt has preempted it. Invoke
+ ``tsp_handle_preemption()`` to handover control back to EL3 by issuing
+ an SMC with ``TSP_PREEMPTED`` as the function identifier.
+
+#. Handles the secure timer interrupt interrupt by acknowledging it using the
+ ``plat_ic_acknowledge_interrupt()`` platform API, calling
+ ``tsp_generic_timer_handler()`` to reprogram the secure physical generic
+ timer and calling the ``plat_ic_end_of_interrupt()`` platform API to signal
+ end of interrupt processing.
+
+The TSP passes control back to the TSPD by issuing an SMC64 with
+``TSP_HANDLED_S_EL1_INTR`` as the function identifier.
+
+The TSP handles interrupts under the asynchronous model as follows.
+
+#. Secure-EL1 interrupts are handled by calling the ``tsp_common_int_handler()``
+ function. The function has been described above.
+
+#. Non-secure interrupts are handled by calling the ``tsp_common_int_handler()``
+ function which ends up invoking ``tsp_handle_preemption()`` and issuing an
+ SMC64 with ``TSP_PREEMPTED`` as the function identifier. Execution resumes at
+ the instruction that follows this SMC instruction when the TSPD hands control
+ to the TSP in response to an SMC with ``TSP_FID_RESUME`` as the function
+ identifier from the non-secure state (see section `Test secure payload
+ dispatcher non-secure interrupt handling`_).
+
+Other considerations
+--------------------
+
+Implication of preempted SMC on Non-Secure Software
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A ``yielding`` SMC call to Secure payload can be preempted by a non-secure
+interrupt and the execution can return to the non-secure world for handling
+the interrupt (For details on ``yielding`` SMC refer `SMC calling convention`_).
+In this case, the SMC call has not completed its execution and the execution
+must return back to the secure payload to resume the preempted SMC call.
+This can be achieved by issuing an SMC call which instructs to resume the
+preempted SMC.
+
+A ``fast`` SMC cannot be preempted and hence this case will not happen for
+a fast SMC call.
+
+In the Test Secure Payload implementation, ``TSP_FID_RESUME`` is designated
+as the resume SMC FID. It is important to note that ``TSP_FID_RESUME`` is a
+``yielding`` SMC which means it too can be be preempted. The typical non
+secure software sequence for issuing a ``yielding`` SMC would look like this,
+assuming ``P.STATE.I=0`` in the non secure state :
+
+.. code:: c
+
+ int rc;
+ rc = smc(TSP_YIELD_SMC_FID, ...); /* Issue a Yielding SMC call */
+ /* The pending non-secure interrupt is handled by the interrupt handler
+ and returns back here. */
+ while (rc == SMC_PREEMPTED) { /* Check if the SMC call is preempted */
+ rc = smc(TSP_FID_RESUME); /* Issue resume SMC call */
+ }
+
+The ``TSP_YIELD_SMC_FID`` is any ``yielding`` SMC function identifier and the smc()
+function invokes a SMC call with the required arguments. The pending non-secure
+interrupt causes an IRQ exception and the IRQ handler registered at the
+exception vector handles the non-secure interrupt and returns. The return value
+from the SMC call is tested for ``SMC_PREEMPTED`` to check whether it is
+preempted. If it is, then the resume SMC call ``TSP_FID_RESUME`` is issued. The
+return value of the SMC call is tested again to check if it is preempted.
+This is done in a loop till the SMC call succeeds or fails. If a ``yielding``
+SMC is preempted, until it is resumed using ``TSP_FID_RESUME`` SMC and
+completed, the current TSPD prevents any other SMC call from re-entering
+TSP by returning ``SMC_UNK`` error.
+
+--------------
+
+*Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _Porting Guide: ../getting_started/porting-guide.rst
+.. _SMC calling convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+
+.. |Image 1| image:: diagrams/sec-int-handling.png?raw=true
+.. |Image 2| image:: diagrams/non-sec-int-handling.png?raw=true
--- /dev/null
+PSCI Power Domain Tree design
+=============================
+
+
+
+
+.. contents::
+
+--------------
+
+Requirements
+------------
+
+#. A platform must export the ``plat_get_aff_count()`` and
+ ``plat_get_aff_state()`` APIs to enable the generic PSCI code to
+ populate a tree that describes the hierarchy of power domains in the
+ system. This approach is inflexible because a change to the topology
+ requires a change in the code.
+
+ It would be much simpler for the platform to describe its power domain tree
+ in a data structure.
+
+#. The generic PSCI code generates MPIDRs in order to populate the power domain
+ tree. It also uses an MPIDR to find a node in the tree. The assumption that
+ a platform will use exactly the same MPIDRs as generated by the generic PSCI
+ code is not scalable. The use of an MPIDR also restricts the number of
+ levels in the power domain tree to four.
+
+ Therefore, there is a need to decouple allocation of MPIDRs from the
+ mechanism used to populate the power domain topology tree.
+
+#. The current arrangement of the power domain tree requires a binary search
+ over the sibling nodes at a particular level to find a specified power
+ domain node. During a power management operation, the tree is traversed from
+ a 'start' to an 'end' power level. The binary search is required to find the
+ node at each level. The natural way to perform this traversal is to
+ start from a leaf node and follow the parent node pointer to reach the end
+ level.
+
+ Therefore, there is a need to define data structures that implement the tree in
+ a way which facilitates such a traversal.
+
+#. The attributes of a core power domain differ from the attributes of power
+ domains at higher levels. For example, only a core power domain can be identified
+ using an MPIDR. There is no requirement to perform state coordination while
+ performing a power management operation on the core power domain.
+
+ Therefore, there is a need to implement the tree in a way which facilitates this
+ distinction between a leaf and non-leaf node and any associated
+ optimizations.
+
+--------------
+
+Design
+------
+
+Describing a power domain tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To fulfill requirement 1., the existing platform APIs
+``plat_get_aff_count()`` and ``plat_get_aff_state()`` have been
+removed. A platform must define an array of unsigned chars such that:
+
+#. The first entry in the array specifies the number of power domains at the
+ highest power level implemented in the platform. This caters for platforms
+ where the power domain tree does not have a single root node, for example,
+ the FVP has two cluster power domains at the highest level (1).
+
+#. Each subsequent entry corresponds to a power domain and contains the number
+ of power domains that are its direct children.
+
+#. The size of the array minus the first entry will be equal to the number of
+ non-leaf power domains.
+
+#. The value in each entry in the array is used to find the number of entries
+ to consider at the next level. The sum of the values (number of children) of
+ all the entries at a level specifies the number of entries in the array for
+ the next level.
+
+The following example power domain topology tree will be used to describe the
+above text further. The leaf and non-leaf nodes in this tree have been numbered
+separately.
+
+::
+
+ +-+
+ |0|
+ +-+
+ / \
+ / \
+ / \
+ / \
+ / \
+ / \
+ / \
+ / \
+ / \
+ / \
+ +-+ +-+
+ |1| |2|
+ +-+ +-+
+ / \ / \
+ / \ / \
+ / \ / \
+ / \ / \
+ +-+ +-+ +-+ +-+
+ |3| |4| |5| |6|
+ +-+ +-+ +-+ +-+
+ +---+-----+ +----+----| +----+----+ +----+-----+-----+
+ | | | | | | | | | | | | |
+ | | | | | | | | | | | | |
+ v v v v v v v v v v v v v
+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +--+ +--+ +--+
+ |0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |10| |11| |12|
+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +--+ +--+ +--+
+
+This tree is defined by the platform as the array described above as follows:
+
+::
+
+ #define PLAT_NUM_POWER_DOMAINS 20
+ #define PLATFORM_CORE_COUNT 13
+ #define PSCI_NUM_NON_CPU_PWR_DOMAINS \
+ (PLAT_NUM_POWER_DOMAINS - PLATFORM_CORE_COUNT)
+
+ unsigned char plat_power_domain_tree_desc[] = { 1, 2, 2, 2, 3, 3, 3, 4};
+
+Removing assumptions about MPIDRs used in a platform
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To fulfill requirement 2., it is assumed that the platform assigns a
+unique number (core index) between ``0`` and ``PLAT_CORE_COUNT - 1`` to each core
+power domain. MPIDRs could be allocated in any manner and will not be used to
+populate the tree.
+
+``plat_core_pos_by_mpidr(mpidr)`` will return the core index for the core
+corresponding to the MPIDR. It will return an error (-1) if an MPIDR is passed
+which is not allocated or corresponds to an absent core. The semantics of this
+platform API have changed since it is required to validate the passed MPIDR. It
+has been made a mandatory API as a result.
+
+Another mandatory API, ``plat_my_core_pos()`` has been added to return the core
+index for the calling core. This API provides a more lightweight mechanism to get
+the index since there is no need to validate the MPIDR of the calling core.
+
+The platform should assign the core indices (as illustrated in the diagram above)
+such that, if the core nodes are numbered from left to right, then the index
+for a core domain will be the same as the index returned by
+``plat_core_pos_by_mpidr()`` or ``plat_my_core_pos()`` for that core. This
+relationship allows the core nodes to be allocated in a separate array
+(requirement 4.) during ``psci_setup()`` in such an order that the index of the
+core in the array is the same as the return value from these APIs.
+
+Dealing with holes in MPIDR allocation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For platforms where the number of allocated MPIDRs is equal to the number of
+core power domains, for example, Juno and FVPs, the logic to convert an MPIDR to
+a core index should remain unchanged. Both Juno and FVP use a simple collision
+proof hash function to do this.
+
+It is possible that on some platforms, the allocation of MPIDRs is not
+contiguous or certain cores have been disabled. This essentially means that the
+MPIDRs have been sparsely allocated, that is, the size of the range of MPIDRs
+used by the platform is not equal to the number of core power domains.
+
+The platform could adopt one of the following approaches to deal with this
+scenario:
+
+#. Implement more complex logic to convert a valid MPIDR to a core index while
+ maintaining the relationship described earlier. This means that the power
+ domain tree descriptor will not describe any core power domains which are
+ disabled or absent. Entries will not be allocated in the tree for these
+ domains.
+
+#. Treat unallocated MPIDRs and disabled cores as absent but still describe them
+ in the power domain descriptor, that is, the number of core nodes described
+ is equal to the size of the range of MPIDRs allocated. This approach will
+ lead to memory wastage since entries will be allocated in the tree but will
+ allow use of a simpler logic to convert an MPIDR to a core index.
+
+Traversing through and distinguishing between core and non-core power domains
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To fulfill requirement 3 and 4, separate data structures have been defined
+to represent leaf and non-leaf power domain nodes in the tree.
+
+.. code:: c
+
+ /*******************************************************************************
+ * The following two data structures implement the power domain tree. The tree
+ * is used to track the state of all the nodes i.e. power domain instances
+ * described by the platform. The tree consists of nodes that describe CPU power
+ * domains i.e. leaf nodes and all other power domains which are parents of a
+ * CPU power domain i.e. non-leaf nodes.
+ ******************************************************************************/
+ typedef struct non_cpu_pwr_domain_node {
+ /*
+ * Index of the first CPU power domain node level 0 which has this node
+ * as its parent.
+ */
+ unsigned int cpu_start_idx;
+
+ /*
+ * Number of CPU power domains which are siblings of the domain indexed
+ * by 'cpu_start_idx' i.e. all the domains in the range 'cpu_start_idx
+ * -> cpu_start_idx + ncpus' have this node as their parent.
+ */
+ unsigned int ncpus;
+
+ /* Index of the parent power domain node */
+ unsigned int parent_node;
+
+ -----
+ } non_cpu_pd_node_t;
+
+ typedef struct cpu_pwr_domain_node {
+ u_register_t mpidr;
+
+ /* Index of the parent power domain node */
+ unsigned int parent_node;
+
+ -----
+ } cpu_pd_node_t;
+
+The power domain tree is implemented as a combination of the following data
+structures.
+
+::
+
+ non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS];
+ cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
+
+Populating the power domain tree
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``populate_power_domain_tree()`` function in ``psci_setup.c`` implements the
+algorithm to parse the power domain descriptor exported by the platform to
+populate the two arrays. It is essentially a breadth-first-search. The nodes for
+each level starting from the root are laid out one after another in the
+``psci_non_cpu_pd_nodes`` and ``psci_cpu_pd_nodes`` arrays as follows:
+
+::
+
+ psci_non_cpu_pd_nodes -> [[Level 3 nodes][Level 2 nodes][Level 1 nodes]]
+ psci_cpu_pd_nodes -> [Level 0 nodes]
+
+For the example power domain tree illustrated above, the ``psci_cpu_pd_nodes``
+will be populated as follows. The value in each entry is the index of the parent
+node. Other fields have been ignored for simplicity.
+
+::
+
+ +-------------+ ^
+ CPU0 | 3 | |
+ +-------------+ |
+ CPU1 | 3 | |
+ +-------------+ |
+ CPU2 | 3 | |
+ +-------------+ |
+ CPU3 | 4 | |
+ +-------------+ |
+ CPU4 | 4 | |
+ +-------------+ |
+ CPU5 | 4 | | PLATFORM_CORE_COUNT
+ +-------------+ |
+ CPU6 | 5 | |
+ +-------------+ |
+ CPU7 | 5 | |
+ +-------------+ |
+ CPU8 | 5 | |
+ +-------------+ |
+ CPU9 | 6 | |
+ +-------------+ |
+ CPU10 | 6 | |
+ +-------------+ |
+ CPU11 | 6 | |
+ +-------------+ |
+ CPU12 | 6 | v
+ +-------------+
+
+The ``psci_non_cpu_pd_nodes`` array will be populated as follows. The value in
+each entry is the index of the parent node.
+
+::
+
+ +-------------+ ^
+ PD0 | -1 | |
+ +-------------+ |
+ PD1 | 0 | |
+ +-------------+ |
+ PD2 | 0 | |
+ +-------------+ |
+ PD3 | 1 | | PLAT_NUM_POWER_DOMAINS -
+ +-------------+ | PLATFORM_CORE_COUNT
+ PD4 | 1 | |
+ +-------------+ |
+ PD5 | 2 | |
+ +-------------+ |
+ PD6 | 2 | |
+ +-------------+ v
+
+Each core can find its node in the ``psci_cpu_pd_nodes`` array using the
+``plat_my_core_pos()`` function. When a core is turned on, the normal world
+provides an MPIDR. The ``plat_core_pos_by_mpidr()`` function is used to validate
+the MPIDR before using it to find the corresponding core node. The non-core power
+domain nodes do not need to be identified.
+
+--------------
+
+*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
--- /dev/null
+Trusted Firmware-A reset design
+===============================
+
+
+
+
+.. contents::
+
+This document describes the high-level design of the framework to handle CPU
+resets in Trusted Firmware-A (TF-A). It also describes how the platform
+integrator can tailor this code to the system configuration to some extent,
+resulting in a simplified and more optimised boot flow.
+
+This document should be used in conjunction with the `Firmware Design`_, which
+provides greater implementation details around the reset code, specifically
+for the cold boot path.
+
+General reset code flow
+-----------------------
+
+The TF-A reset code is implemented in BL1 by default. The following high-level
+diagram illustrates this:
+
+|Default reset code flow|
+
+This diagram shows the default, unoptimised reset flow. Depending on the system
+configuration, some of these steps might be unnecessary. The following sections
+guide the platform integrator by indicating which build options exclude which
+steps, depending on the capability of the platform.
+
+Note: If BL31 is used as the TF-A entry point instead of BL1, the diagram
+above is still relevant, as all these operations will occur in BL31 in
+this case. Please refer to section 6 "Using BL31 entrypoint as the reset
+address" for more information.
+
+Programmable CPU reset address
+------------------------------
+
+By default, TF-A assumes that the CPU reset address is not programmable.
+Therefore, all CPUs start at the same address (typically address 0) whenever
+they reset. Further logic is then required to identify whether it is a cold or
+warm boot to direct CPUs to the right execution path.
+
+If the reset vector address (reflected in the reset vector base address register
+``RVBAR_EL3``) is programmable then it is possible to make each CPU start directly
+at the right address, both on a cold and warm reset. Therefore, the boot type
+detection can be skipped, resulting in the following boot flow:
+
+|Reset code flow with programmable reset address|
+
+To enable this boot flow, compile TF-A with ``PROGRAMMABLE_RESET_ADDRESS=1``.
+This option only affects the TF-A reset image, which is BL1 by default or BL31 if
+``RESET_TO_BL31=1``.
+
+On both the FVP and Juno platforms, the reset vector address is not programmable
+so both ports use ``PROGRAMMABLE_RESET_ADDRESS=0``.
+
+Cold boot on a single CPU
+-------------------------
+
+By default, TF-A assumes that several CPUs may be released out of reset.
+Therefore, the cold boot code has to arbitrate access to hardware resources
+shared amongst CPUs. This is done by nominating one of the CPUs as the primary,
+which is responsible for initialising shared hardware and coordinating the boot
+flow with the other CPUs.
+
+If the platform guarantees that only a single CPU will ever be brought up then
+no arbitration is required. The notion of primary/secondary CPU itself no longer
+applies. This results in the following boot flow:
+
+|Reset code flow with single CPU released out of reset|
+
+To enable this boot flow, compile TF-A with ``COLD_BOOT_SINGLE_CPU=1``. This
+option only affects the TF-A reset image, which is BL1 by default or BL31 if
+``RESET_TO_BL31=1``.
+
+On both the FVP and Juno platforms, although only one core is powered up by
+default, there are platform-specific ways to release any number of cores out of
+reset. Therefore, both platform ports use ``COLD_BOOT_SINGLE_CPU=0``.
+
+Programmable CPU reset address, Cold boot on a single CPU
+---------------------------------------------------------
+
+It is obviously possible to combine both optimisations on platforms that have
+a programmable CPU reset address and which release a single CPU out of reset.
+This results in the following boot flow:
+
+
+|Reset code flow with programmable reset address and single CPU released out of reset|
+
+To enable this boot flow, compile TF-A with both ``COLD_BOOT_SINGLE_CPU=1``
+and ``PROGRAMMABLE_RESET_ADDRESS=1``. These options only affect the TF-A reset
+image, which is BL1 by default or BL31 if ``RESET_TO_BL31=1``.
+
+Using BL31 entrypoint as the reset address
+------------------------------------------
+
+On some platforms the runtime firmware (BL3x images) for the application
+processors are loaded by some firmware running on a secure system processor
+on the SoC, rather than by BL1 and BL2 running on the primary application
+processor. For this type of SoC it is desirable for the application processor
+to always reset to BL31 which eliminates the need for BL1 and BL2.
+
+TF-A provides a build-time option ``RESET_TO_BL31`` that includes some additional
+logic in the BL31 entry point to support this use case.
+
+In this configuration, the platform's Trusted Boot Firmware must ensure that
+BL31 is loaded to its runtime address, which must match the CPU's ``RVBAR_EL3``
+reset vector base address, before the application processor is powered on.
+Additionally, platform software is responsible for loading the other BL3x images
+required and providing entry point information for them to BL31. Loading these
+images might be done by the Trusted Boot Firmware or by platform code in BL31.
+
+Although the Arm FVP platform does not support programming the reset base
+address dynamically at run-time, it is possible to set the initial value of the
+``RVBAR_EL3`` register at start-up. This feature is provided on the Base FVP only.
+It allows the Arm FVP port to support the ``RESET_TO_BL31`` configuration, in
+which case the ``bl31.bin`` image must be loaded to its run address in Trusted
+SRAM and all CPU reset vectors be changed from the default ``0x0`` to this run
+address. See the `User Guide`_ for details of running the FVP models in this way.
+
+Although technically it would be possible to program the reset base address with
+the right support in the SCP firmware, this is currently not implemented so the
+Juno port doesn't support the ``RESET_TO_BL31`` configuration.
+
+The ``RESET_TO_BL31`` configuration requires some additions and changes in the
+BL31 functionality:
+
+Determination of boot path
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In this configuration, BL31 uses the same reset framework and code as the one
+described for BL1 above. Therefore, it is affected by the
+``PROGRAMMABLE_RESET_ADDRESS`` and ``COLD_BOOT_SINGLE_CPU`` build options in the
+same way.
+
+In the default, unoptimised BL31 reset flow, on a warm boot a CPU is directed
+to the PSCI implementation via a platform defined mechanism. On a cold boot,
+the platform must place any secondary CPUs into a safe state while the primary
+CPU executes a modified BL31 initialization, as described below.
+
+Platform initialization
+~~~~~~~~~~~~~~~~~~~~~~~
+
+In this configuration, when the CPU resets to BL31 there are no parameters that
+can be passed in registers by previous boot stages. Instead, the platform code
+in BL31 needs to know, or be able to determine, the location of the BL32 (if
+required) and BL33 images and provide this information in response to the
+``bl31_plat_get_next_image_ep_info()`` function.
+
+Additionally, platform software is responsible for carrying out any security
+initialisation, for example programming a TrustZone address space controller.
+This might be done by the Trusted Boot Firmware or by platform code in BL31.
+
+--------------
+
+*Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _Firmware Design: firmware-design.rst
+.. _User Guide: ../getting_started/user-guide.rst
+
+.. |Default reset code flow| image:: ../diagrams/default_reset_code.png?raw=true
+.. |Reset code flow with programmable reset address| image:: ../diagrams/reset_code_no_boot_type_check.png?raw=true
+.. |Reset code flow with single CPU released out of reset| image:: ../diagrams/reset_code_no_cpu_check.png?raw=true
+.. |Reset code flow with programmable reset address and single CPU released out of reset| image:: ../diagrams/reset_code_no_checks.png?raw=true
--- /dev/null
+Trusted Board Boot Design Guide
+===============================
+
+
+
+
+.. contents::
+
+The Trusted Board Boot (TBB) feature prevents malicious firmware from running on
+the platform by authenticating all firmware images up to and including the
+normal world bootloader. It does this by establishing a Chain of Trust using
+Public-Key-Cryptography Standards (PKCS).
+
+This document describes the design of Trusted Firmware-A (TF-A) TBB, which is an
+implementation of the `Trusted Board Boot Requirements (TBBR)`_ specification,
+Arm DEN0006D. It should be used in conjunction with the `Firmware Update`_
+design document, which implements a specific aspect of the TBBR.
+
+Chain of Trust
+--------------
+
+A Chain of Trust (CoT) starts with a set of implicitly trusted components. On
+the Arm development platforms, these components are:
+
+- A SHA-256 hash of the Root of Trust Public Key (ROTPK). It is stored in the
+ trusted root-key storage registers.
+
+- The BL1 image, on the assumption that it resides in ROM so cannot be
+ tampered with.
+
+The remaining components in the CoT are either certificates or boot loader
+images. The certificates follow the `X.509 v3`_ standard. This standard
+enables adding custom extensions to the certificates, which are used to store
+essential information to establish the CoT.
+
+In the TBB CoT all certificates are self-signed. There is no need for a
+Certificate Authority (CA) because the CoT is not established by verifying the
+validity of a certificate's issuer but by the content of the certificate
+extensions. To sign the certificates, the PKCS#1 SHA-256 with RSA Encryption
+signature scheme is used with a RSA key length of 2048 bits. Future version of
+TF-A will support additional cryptographic algorithms.
+
+The certificates are categorised as "Key" and "Content" certificates. Key
+certificates are used to verify public keys which have been used to sign content
+certificates. Content certificates are used to store the hash of a boot loader
+image. An image can be authenticated by calculating its hash and matching it
+with the hash extracted from the content certificate. The SHA-256 function is
+used to calculate all hashes. The public keys and hashes are included as
+non-standard extension fields in the `X.509 v3`_ certificates.
+
+The keys used to establish the CoT are:
+
+- **Root of trust key**
+
+ The private part of this key is used to sign the BL2 content certificate and
+ the trusted key certificate. The public part is the ROTPK.
+
+- **Trusted world key**
+
+ The private part is used to sign the key certificates corresponding to the
+ secure world images (SCP_BL2, BL31 and BL32). The public part is stored in
+ one of the extension fields in the trusted world certificate.
+
+- **Non-trusted world key**
+
+ The private part is used to sign the key certificate corresponding to the
+ non secure world image (BL33). The public part is stored in one of the
+ extension fields in the trusted world certificate.
+
+- **BL3-X keys**
+
+ For each of SCP_BL2, BL31, BL32 and BL33, the private part is used to
+ sign the content certificate for the BL3-X image. The public part is stored
+ in one of the extension fields in the corresponding key certificate.
+
+The following images are included in the CoT:
+
+- BL1
+- BL2
+- SCP_BL2 (optional)
+- BL31
+- BL33
+- BL32 (optional)
+
+The following certificates are used to authenticate the images.
+
+- **BL2 content certificate**
+
+ It is self-signed with the private part of the ROT key. It contains a hash
+ of the BL2 image.
+
+- **Trusted key certificate**
+
+ It is self-signed with the private part of the ROT key. It contains the
+ public part of the trusted world key and the public part of the non-trusted
+ world key.
+
+- **SCP_BL2 key certificate**
+
+ It is self-signed with the trusted world key. It contains the public part of
+ the SCP_BL2 key.
+
+- **SCP_BL2 content certificate**
+
+ It is self-signed with the SCP_BL2 key. It contains a hash of the SCP_BL2
+ image.
+
+- **BL31 key certificate**
+
+ It is self-signed with the trusted world key. It contains the public part of
+ the BL31 key.
+
+- **BL31 content certificate**
+
+ It is self-signed with the BL31 key. It contains a hash of the BL31 image.
+
+- **BL32 key certificate**
+
+ It is self-signed with the trusted world key. It contains the public part of
+ the BL32 key.
+
+- **BL32 content certificate**
+
+ It is self-signed with the BL32 key. It contains a hash of the BL32 image.
+
+- **BL33 key certificate**
+
+ It is self-signed with the non-trusted world key. It contains the public
+ part of the BL33 key.
+
+- **BL33 content certificate**
+
+ It is self-signed with the BL33 key. It contains a hash of the BL33 image.
+
+The SCP_BL2 and BL32 certificates are optional, but they must be present if the
+corresponding SCP_BL2 or BL32 images are present.
+
+Trusted Board Boot Sequence
+---------------------------
+
+The CoT is verified through the following sequence of steps. The system panics
+if any of the steps fail.
+
+- BL1 loads and verifies the BL2 content certificate. The issuer public key is
+ read from the verified certificate. A hash of that key is calculated and
+ compared with the hash of the ROTPK read from the trusted root-key storage
+ registers. If they match, the BL2 hash is read from the certificate.
+
+ Note: the matching operation is platform specific and is currently
+ unimplemented on the Arm development platforms.
+
+- BL1 loads the BL2 image. Its hash is calculated and compared with the hash
+ read from the certificate. Control is transferred to the BL2 image if all
+ the comparisons succeed.
+
+- BL2 loads and verifies the trusted key certificate. The issuer public key is
+ read from the verified certificate. A hash of that key is calculated and
+ compared with the hash of the ROTPK read from the trusted root-key storage
+ registers. If the comparison succeeds, BL2 reads and saves the trusted and
+ non-trusted world public keys from the verified certificate.
+
+The next two steps are executed for each of the SCP_BL2, BL31 & BL32 images.
+The steps for the optional SCP_BL2 and BL32 images are skipped if these images
+are not present.
+
+- BL2 loads and verifies the BL3x key certificate. The certificate signature
+ is verified using the trusted world public key. If the signature
+ verification succeeds, BL2 reads and saves the BL3x public key from the
+ certificate.
+
+- BL2 loads and verifies the BL3x content certificate. The signature is
+ verified using the BL3x public key. If the signature verification succeeds,
+ BL2 reads and saves the BL3x image hash from the certificate.
+
+The next two steps are executed only for the BL33 image.
+
+- BL2 loads and verifies the BL33 key certificate. If the signature
+ verification succeeds, BL2 reads and saves the BL33 public key from the
+ certificate.
+
+- BL2 loads and verifies the BL33 content certificate. If the signature
+ verification succeeds, BL2 reads and saves the BL33 image hash from the
+ certificate.
+
+The next step is executed for all the boot loader images.
+
+- BL2 calculates the hash of each image. It compares it with the hash obtained
+ from the corresponding content certificate. The image authentication succeeds
+ if the hashes match.
+
+The Trusted Board Boot implementation spans both generic and platform-specific
+BL1 and BL2 code, and in tool code on the host build machine. The feature is
+enabled through use of specific build flags as described in the `User Guide`_.
+
+On the host machine, a tool generates the certificates, which are included in
+the FIP along with the boot loader images. These certificates are loaded in
+Trusted SRAM using the IO storage framework. They are then verified by an
+Authentication module included in TF-A.
+
+The mechanism used for generating the FIP and the Authentication module are
+described in the following sections.
+
+Authentication Framework
+------------------------
+
+The authentication framework included in TF-A provides support to implement
+the desired trusted boot sequence. Arm platforms use this framework to
+implement the boot requirements specified in the `TBBR-client`_ document.
+
+More information about the authentication framework can be found in the
+`Auth Framework`_ document.
+
+Certificate Generation Tool
+---------------------------
+
+The ``cert_create`` tool is built and runs on the host machine as part of the
+TF-A build process when ``GENERATE_COT=1``. It takes the boot loader images
+and keys as inputs (keys must be in PEM format) and generates the
+certificates (in DER format) required to establish the CoT. New keys can be
+generated by the tool in case they are not provided. The certificates are then
+passed as inputs to the ``fiptool`` utility for creating the FIP.
+
+The certificates are also stored individually in the in the output build
+directory.
+
+The tool resides in the ``tools/cert_create`` directory. It uses OpenSSL SSL
+library version 1.0.1 or later to generate the X.509 certificates. Instructions
+for building and using the tool can be found in the `User Guide`_.
+
+--------------
+
+*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _Firmware Update: firmware-update.rst
+.. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt
+.. _User Guide: ../getting_started/user-guide.rst
+.. _Auth Framework: auth-framework.rst
+.. _TBBR-client: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _Trusted Board Boot Requirements (TBBR): `TBBR-client`_
+++ /dev/null
-Exception Handling Framework in Trusted Firmware-A
-==================================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
- :depth: 2
-
-.. |EHF| replace:: Exception Handling Framework
-.. |TF-A| replace:: Trusted Firmware-A
-
-This document describes various aspects of handling exceptions by Runtime
-Firmware (BL31) that are targeted at EL3, other than SMCs. The |EHF| takes care
-of the following exceptions when targeted at EL3:
-
-- Interrupts
-- Synchronous External Aborts
-- Asynchronous External Aborts
-
-|TF-A|'s handling of synchronous ``SMC`` exceptions raised from lower ELs is
-described in the `Firmware Design document`__. However, the |EHF| changes the
-semantics of `interrupt handling`__ and `synchronous exceptions`__ other than
-SMCs.
-
-.. __: firmware-design.rst#handling-an-smc
-.. __: `Interrupt handling`_
-.. __: `Effect on SMC calls`_
-
-The |EHF| is selected by setting the build option ``EL3_EXCEPTION_HANDLING`` to
-``1``, and is only available for AArch64 systems.
-
-Introduction
-------------
-
-Through various control bits in the ``SCR_EL3`` register, the Arm architecture
-allows for asynchronous exceptions to be routed to EL3. As described in the
-`Interrupt Framework Design`_ document, depending on the chosen interrupt
-routing model, TF-A appropriately sets the ``FIQ`` and ``IRQ`` bits of
-``SCR_EL3`` register to effect this routing. For most use cases, other than for
-the purpose of facilitating context switch between Normal and Secure worlds,
-FIQs and IRQs routed to EL3 are not required to be handled in EL3.
-
-However, the evolving system and standards landscape demands that various
-exceptions are targeted at and handled in EL3. For instance:
-
-- Starting with ARMv8.2 architecture extension, many RAS features have been
- introduced to the Arm architecture. With RAS features implemented, various
- components of the system may use one of the asynchronous exceptions to signal
- error conditions to PEs. These error conditions are of critical nature, and
- it's imperative that corrective or remedial actions are taken at the earliest
- opportunity. Therefore, a *Firmware-first Handling* approach is generally
- followed in response to RAS events in the system.
-
-- The Arm `SDEI specification`_ defines interfaces through which Normal world
- interacts with the Runtime Firmware in order to request notification of
- system events. The SDEI specification requires that these events are notified
- even when the Normal world executes with the exceptions masked. This too
- implies that firmware-first handling is required, where the events are first
- received by the EL3 firmware, and then dispatched to Normal world through
- purely software mechanism.
-
-For |TF-A|, firmware-first handling means that asynchronous exceptions are
-suitably routed to EL3, and the Runtime Firmware (BL31) is extended to include
-software components that are capable of handling those exceptions that target
-EL3. These components—referred to as *dispatchers* [#spd]_ in general—may
-choose to:
-
-.. _delegation-use-cases:
-
-- Receive and handle exceptions entirely in EL3, meaning the exceptions
- handling terminates in EL3.
-
-- Receive exceptions, but handle part of the exception in EL3, and delegate the
- rest of the handling to a dedicated software stack running at lower Secure
- ELs. In this scheme, the handling spans various secure ELs.
-
-- Receive exceptions, but handle part of the exception in EL3, and delegate
- processing of the error to dedicated software stack running at lower secure
- ELs (as above); additionally, the Normal world may also be required to
- participate in the handling, or be notified of such events (for example, as
- an SDEI event). In this scheme, exception handling potentially and maximally
- spans all ELs in both Secure and Normal worlds.
-
-On any given system, all of the above handling models may be employed
-independently depending on platform choice and the nature of the exception
-received.
-
-.. [#spd] Not to be confused with `Secure Payload Dispatcher`__, which is an
- EL3 component that operates in EL3 on behalf of Secure OS.
-
-.. __: firmware-design.rst#secure-el1-payloads-and-dispatchers
-
-The role of Exception Handling Framework
-----------------------------------------
-
-Corollary to the use cases cited above, the primary role of the |EHF| is to
-facilitate firmware-first handling of exceptions on Arm systems. The |EHF| thus
-enables multiple exception dispatchers in runtime firmware to co-exist, register
-for, and handle exceptions targeted at EL3. This section outlines the basics,
-and the rest of this document expands the various aspects of the |EHF|.
-
-In order to arbitrate exception handling among dispatchers, the |EHF| operation
-is based on a priority scheme. This priority scheme is closely tied to how the
-Arm GIC architecture defines it, although it's applied to non-interrupt
-exceptions too (SErrors, for example).
-
-The platform is required to `partition`__ the Secure priority space into
-priority levels as applicable for the Secure software stack. It then assigns the
-dispatchers to one or more priority levels. The dispatchers then register
-handlers for the priority levels at runtime. A dispatcher can register handlers
-for more than one priority level.
-
-.. __: `Partitioning priority levels`_
-
-
-.. _ehf-figure:
-
-.. image:: draw.io/ehf.svg
-
-A priority level is *active* when a handler at that priority level is currently
-executing in EL3, or has delegated the execution to a lower EL. For interrupts,
-this is implicit when an interrupt is targeted and acknowledged at EL3, and the
-priority of the acknowledged interrupt is used to match its registered handler.
-The priority level is likewise implicitly deactivated when the interrupt
-handling concludes by EOIing the interrupt.
-
-Non-interrupt exceptions (SErrors, for example) don't have a notion of priority.
-In order for the priority arbitration to work, the |EHF| provides APIs in order
-for these non-interrupt exceptions to assume a priority, and to interwork with
-interrupts. Dispatchers handling such exceptions must therefore explicitly
-activate and deactivate the respective priority level as and when they're
-handled or delegated.
-
-Because priority activation and deactivation for interrupt handling is implicit
-and involves GIC priority masking, it's impossible for a lower priority
-interrupt to preempt a higher priority one. By extension, this means that a
-lower priority dispatcher cannot preempt a higher-priority one. Priority
-activation and deactivation for non-interrupt exceptions, however, has to be
-explicit. The |EHF| therefore disallows for lower priority level to be activated
-whilst a higher priority level is active, and would result in a panic.
-Likewise, a panic would result if it's attempted to deactivate a lower priority
-level when a higher priority level is active.
-
-In essence, priority level activation and deactivation conceptually works like a
-stack—priority levels stack up in strictly increasing fashion, and need to be
-unstacked in strictly the reverse order. For interrupts, the GIC ensures this is
-the case; for non-interrupts, the |EHF| monitors and asserts this. See
-`Transition of priority levels`_.
-
-Interrupt handling
-------------------
-
-The |EHF| is a client of *Interrupt Management Framework*, and registers the
-top-level handler for interrupts that target EL3, as described in the `Interrupt
-Framework Design`_ document. This has the following implications.
-
-- On GICv3 systems, when executing in S-EL1, pending Non-secure interrupts of
- sufficient priority are signalled as FIQs, and therefore will be routed to
- EL3. As a result, S-EL1 software cannot expect to handle Non-secure
- interrupts at S-EL1. Essentially, this deprecates the routing mode described
- as `CSS=0, TEL3=0`__.
-
- .. __: interrupt-framework-design.rst#el3-interrupts
-
- In order for S-EL1 software to handle Non-secure interrupts while having
- |EHF| enabled, the dispatcher must adopt a model where Non-secure interrupts
- are received at EL3, but are then `synchronously`__ handled over to S-EL1.
-
- .. __: interrupt-framework-design.rst#secure-payload
-
-- On GICv2 systems, it's required that the build option ``GICV2_G0_FOR_EL3`` is
- set to ``1`` so that *Group 0* interrupts target EL3.
-
-- While executing in Secure world, |EHF| sets GIC Priority Mask Register to the
- lowest Secure priority. This means that no Non-secure interrupts can preempt
- Secure execution. See `Effect on SMC calls`_ for more details.
-
-As mentioned above, with |EHF|, the platform is required to partition *Group 0*
-interrupts into distinct priority levels. A dispatcher that chooses to receive
-interrupts can then *own* one or more priority levels, and register interrupt
-handlers for them. A given priority level can be assigned to only one handler. A
-dispatcher may register more than one priority level.
-
-Dispatchers are assigned interrupt priority levels in two steps:
-
-Partitioning priority levels
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Interrupts are associated to dispatchers by way of grouping and assigning
-interrupts to a priority level. In other words, all interrupts that are to
-target a particular dispatcher should fall in a particular priority level. For
-priority assignment:
-
-- Of the 8 bits of priority that Arm GIC architecture permits, bit 7 must be 0
- (secure space).
-
-- Depending on the number of dispatchers to support, the platform must choose
- to use the top *n* of the 7 remaining bits to identify and assign interrupts
- to individual dispatchers. Choosing *n* bits supports up to 2\ :sup:`n`
- distinct dispatchers. For example, by choosing 2 additional bits (i.e., bits
- 6 and 5), the platform can partition into 4 secure priority ranges: ``0x0``,
- ``0x20``, ``0x40``, and ``0x60``. See `Interrupt handling example`_.
-
-Note:
-
- The Arm GIC architecture requires that a GIC implementation that supports two
- security states must implement at least 32 priority levels; i.e., at least 5
- upper bits of the 8 bits are writeable. In the scheme described above, when
- choosing *n* bits for priority range assignment, the platform must ensure
- that at least ``n+1`` top bits of GIC priority are writeable.
-
-The priority thus assigned to an interrupt is also used to determine the
-priority of delegated execution in lower ELs. Delegated execution in lower EL is
-associated with a priority level chosen with ``ehf_activate_priority()`` API
-(described `later`__). The chosen priority level also determines the interrupts
-masked while executing in a lower EL, therefore controls preemption of delegated
-execution.
-
-.. __: `ehf-apis`_
-
-The platform expresses the chosen priority levels by declaring an array of
-priority level descriptors. Each entry in the array is of type
-``ehf_pri_desc_t``, and declares a priority level, and shall be populated by the
-``EHF_PRI_DESC()`` macro.
-
-Note:
-
- The macro ``EHF_PRI_DESC()`` installs the descriptors in the array at a
- computed index, and not necessarily where the macro is placed in the array.
- The size of the array might therefore be larger than what it appears to be.
- The ``ARRAY_SIZE()`` macro therefore should be used to determine the size of
- array.
-
-Finally, this array of descriptors is exposed to |EHF| via the
-``EHF_REGISTER_PRIORITIES()`` macro.
-
-Refer to the `Interrupt handling example`_ for usage. See also: `Interrupt
-Prioritisation Considerations`_.
-
-Programming priority
-~~~~~~~~~~~~~~~~~~~~
-
-The text in `Partitioning priority levels`_ only describes how the platform
-expresses the required levels of priority. It however doesn't choose interrupts
-nor program the required priority in GIC.
-
-The `Firmware Design guide`__ explains methods for configuring secure
-interrupts. |EHF| requires the platform to enumerate interrupt properties (as
-opposed to just numbers) of Secure interrupts. The priority of secure interrupts
-must match that as determined in the `Partitioning priority levels`_ section above.
-
-.. __: firmware-design.rst#configuring-secure-interrupts
-
-See `Limitations`_, and also refer to `Interrupt handling example`_ for
-illustration.
-
-Registering handler
--------------------
-
-Dispatchers register handlers for their priority levels through the following
-API:
-
-.. code:: c
-
- int ehf_register_priority_handler(int pri, ehf_handler_t handler)
-
-The API takes two arguments:
-
-- The priority level for which the handler is being registered;
-
-- The handler to be registered. The handler must be aligned to 4 bytes.
-
-If a dispatcher owns more than one priority levels, it has to call the API for
-each of them.
-
-The API will succeed, and return ``0``, only if:
-
-- There exists a descriptor with the priority level requested.
-
-- There are no handlers already registered by a previous call to the API.
-
-Otherwise, the API returns ``-1``.
-
-The interrupt handler should have the following signature:
-
-.. code:: c
-
- typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle,
- void *cookie);
-
-The parameters are as obtained from the top-level `EL3 interrupt handler`__.
-
-.. __: interrupt-framework-design.rst#el3-runtime-firmware
-
-The `SDEI dispatcher`__, for example, expects the platform to allocate two
-different priority levels—``PLAT_SDEI_CRITICAL_PRI``, and
-``PLAT_SDEI_NORMAL_PRI``—and registers the same handler to handle both levels.
-
-.. __: sdei.rst
-
-Interrupt handling example
---------------------------
-
-The following annotated snippet demonstrates how a platform might choose to
-assign interrupts to fictitious dispatchers:
-
-.. code:: c
-
- #include <common/interrupt_props.h>
- #include <drivers/arm/gic_common.h>
- #include <exception_mgmt.h>
-
- ...
-
- /*
- * This platform uses 2 bits for interrupt association. In total, 3 upper
- * bits are in use.
- *
- * 7 6 5 3 0
- * .-.-.-.----------.
- * |0|b|b| ..0.. |
- * '-'-'-'----------'
- */
- #define PLAT_PRI_BITS 2
-
- /* Priorities for individual dispatchers */
- #define DISP0_PRIO 0x00 /* Not used */
- #define DISP1_PRIO 0x20
- #define DISP2_PRIO 0x40
- #define DISP3_PRIO 0x60
-
- /* Install priority level descriptors for each dispatcher */
- ehf_pri_desc_t plat_exceptions[] = {
- EHF_PRI_DESC(PLAT_PRI_BITS, DISP1_PRIO),
- EHF_PRI_DESC(PLAT_PRI_BITS, DISP2_PRIO),
- EHF_PRI_DESC(PLAT_PRI_BITS, DISP3_PRIO),
- };
-
- /* Expose priority descriptors to Exception Handling Framework */
- EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions),
- PLAT_PRI_BITS);
-
- ...
-
- /* List interrupt properties for GIC driver. All interrupts target EL3 */
- const interrupt_prop_t plat_interrupts[] = {
- /* Dispatcher 1 owns interrupts d1_0 and d1_1, so assigns priority DISP1_PRIO */
- INTR_PROP_DESC(d1_0, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
- INTR_PROP_DESC(d1_1, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
-
- /* Dispatcher 2 owns interrupts d2_0 and d2_1, so assigns priority DISP2_PRIO */
- INTR_PROP_DESC(d2_0, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
- INTR_PROP_DESC(d2_1, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
-
- /* Dispatcher 3 owns interrupts d3_0 and d3_1, so assigns priority DISP3_PRIO */
- INTR_PROP_DESC(d3_0, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
- INTR_PROP_DESC(d3_1, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL),
- };
-
- ...
-
- /* Dispatcher 1 registers its handler */
- ehf_register_priority_handler(DISP1_PRIO, disp1_handler);
-
- /* Dispatcher 2 registers its handler */
- ehf_register_priority_handler(DISP2_PRIO, disp2_handler);
-
- /* Dispatcher 3 registers its handler */
- ehf_register_priority_handler(DISP3_PRIO, disp3_handler);
-
- ...
-
-See also the `Build-time flow`_ and the `Run-time flow`_.
-
-Activating and Deactivating priorities
---------------------------------------
-
-A priority level is said to be *active* when an exception of that priority is
-being handled: for interrupts, this is implied when the interrupt is
-acknowledged; for non-interrupt exceptions, such as SErrors or `SDEI explicit
-dispatches`__, this has to be done via calling ``ehf_activate_priority()``. See
-`Run-time flow`_.
-
-.. __: sdei.rst#explicit-dispatch-of-events
-
-Conversely, when the dispatcher has reached a logical resolution for the cause
-of the exception, the corresponding priority level ought to be deactivated. As
-above, for interrupts, this is implied when the interrupt is EOId in the GIC;
-for other exceptions, this has to be done via calling
-``ehf_deactivate_priority()``.
-
-Thanks to `different provisions`__ for exception delegation, there are
-potentially more than one work flow for deactivation:
-
-.. __: `delegation-use-cases`_
-
-.. _deactivation workflows:
-
-- The dispatcher has addressed the cause of the exception, and decided to take
- no further action. In this case, the dispatcher's handler deactivates the
- priority level before returning to the |EHF|. Runtime firmware, upon exit
- through an ``ERET``, resumes execution before the interrupt occurred.
-
-- The dispatcher has to delegate the execution to lower ELs, and the cause of
- the exception can be considered resolved only when the lower EL returns
- signals complete (via an ``SMC``) at a future point in time. The following
- sequence ensues:
-
- #. The dispatcher calls ``setjmp()`` to setup a jump point, and arranges to
- enter a lower EL upon the next ``ERET``.
-
- #. Through the ensuing ``ERET`` from runtime firmware, execution is delegated
- to a lower EL.
-
- #. The lower EL completes its execution, and signals completion via an
- ``SMC``.
-
- #. The ``SMC`` is handled by the same dispatcher that handled the exception
- previously. Noticing the conclusion of exception handling, the dispatcher
- does ``longjmp()`` to resume beyond the previous jump point.
-
-As mentioned above, the |EHF| provides the following APIs for activating and
-deactivating interrupt:
-
-.. _ehf-apis:
-
-- ``ehf_activate_priority()`` activates the supplied priority level, but only
- if the current active priority is higher than the given one; otherwise
- panics. Also, to prevent interruption by physical interrupts of lower
- priority, the |EHF| programs the *Priority Mask Register* corresponding to
- the PE to the priority being activated. Dispatchers typically only need to
- call this when handling exceptions other than interrupts, and it needs to
- delegate execution to a lower EL at a desired priority level.
-
-- ``ehf_deactivate_priority()`` deactivates a given priority, but only if the
- current active priority is equal to the given one; otherwise panics. |EHF|
- also restores the *Priority Mask Register* corresponding to the PE to the
- priority before the call to ``ehf_activate_priority()``. Dispatchers
- typically only need to call this after handling exceptions other than
- interrupts.
-
-The calling of APIs are subject to allowed `transitions`__. See also the
-`Run-time flow`_.
-
-.. __: `Transition of priority levels`_
-
-Transition of priority levels
------------------------------
-
-The |EHF| APIs ``ehf_activate_priority()`` and ``ehf_deactivate_priority()`` can
-be called to transition the current priority level on a PE. A given sequence of
-calls to these APIs are subject to the following conditions:
-
-- For activation, the |EHF| only allows for the priority to increase (i.e.
- numeric value decreases);
-
-- For deactivation, the |EHF| only allows for the priority to decrease (i.e.
- numeric value increases). Additionally, the priority being deactivated is
- required to be the current priority.
-
-If these are violated, a panic will result.
-
-Effect on SMC calls
--------------------
-
-In general, Secure execution is regarded as more important than Non-secure
-execution. As discussed elsewhere in this document, EL3 execution, and any
-delegated execution thereafter, has the effect of raising GIC's priority
-mask—either implicitly by acknowledging Secure interrupts, or when dispatchers
-call ``ehf_activate_priority()``. As a result, Non-secure interrupts cannot
-preempt any Secure execution.
-
-SMCs from Non-secure world are synchronous exceptions, and are mechanisms for
-Non-secure world to request Secure services. They're broadly classified as
-*Fast* or *Yielding* (see `SMCCC`__).
-
-.. __: `http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html`
-
-- *Fast* SMCs are atomic from the caller's point of view. I.e., they return
- to the caller only when the Secure world has finished serving the request.
- Any Non-secure interrupts that become pending meanwhile cannot preempt Secure
- execution.
-
-- *Yielding* SMCs carry the semantics of a preemptible, lower-priority request.
- A pending Non-secure interrupt can preempt Secure execution handling a
- Yielding SMC. I.e., the caller might observe a Yielding SMC returning when
- either:
-
- #. Secure world completes the request, and the caller would find ``SMC_OK``
- as the return code.
-
- #. A Non-secure interrupt preempts Secure execution. Non-secure interrupt is
- handled, and Non-secure execution resumes after ``SMC`` instruction.
-
- The dispatcher handling a Yielding SMC must provide a different return code
- to the Non-secure caller to distinguish the latter case. This return code,
- however, is not standardised (unlike ``SMC_UNKNOWN`` or ``SMC_OK``, for
- example), so will vary across dispatchers that handle the request.
-
-For the latter case above, dispatchers before |EHF| expect Non-secure interrupts
-to be taken to S-EL1 [#irq]_, so would get a chance to populate the designated
-preempted error code before yielding to Non-secure world.
-
-The introduction of |EHF| changes the behaviour as described in `Interrupt
-handling`_.
-
-When |EHF| is enabled, in order to allow Non-secure interrupts to preempt
-Yielding SMC handling, the dispatcher must call ``ehf_allow_ns_preemption()``
-API. The API takes one argument, the error code to be returned to the Non-secure
-world upon getting preempted.
-
-.. [#irq] In case of GICv2, Non-secure interrupts while in S-EL1 were signalled
- as IRQs, and in case of GICv3, FIQs.
-
-Build-time flow
----------------
-
-Please refer to the `figure`__ above.
-
-.. __: `ehf-figure`_
-
-The build-time flow involves the following steps:
-
-#. Platform assigns priorities by installing priority level descriptors for
- individual dispatchers, as described in `Partitioning priority levels`_.
-
-#. Platform provides interrupt properties to GIC driver, as described in
- `Programming priority`_.
-
-#. Dispatcher calling ``ehf_register_priority_handler()`` to register an
- interrupt handler.
-
-Also refer to the `Interrupt handling example`_.
-
-Run-time flow
--------------
-
-.. _interrupt-flow:
-
-The following is an example flow for interrupts:
-
-#. The GIC driver, during initialization, iterates through the platform-supplied
- interrupt properties (see `Programming priority`_), and configures the
- interrupts. This programs the appropriate priority and group (Group 0) on
- interrupts belonging to different dispatchers.
-
-#. The |EHF|, during its initialisation, registers a top-level interrupt handler
- with the `Interrupt Management Framework`__ for EL3 interrupts. This also
- results in setting the routing bits in ``SCR_EL3``.
-
- .. __: interrupt-framework-design.rst#el3-runtime-firmware
-
-#. When an interrupt belonging to a dispatcher fires, GIC raises an EL3/Group 0
- interrupt, and is taken to EL3.
-
-#. The top-level EL3 interrupt handler executes. The handler acknowledges the
- interrupt, reads its *Running Priority*, and from that, determines the
- dispatcher handler.
-
-#. The |EHF| programs the *Priority Mask Register* of the PE to the priority of
- the interrupt received.
-
-#. The |EHF| marks that priority level *active*, and jumps to the dispatcher
- handler.
-
-#. Once the dispatcher handler finishes its job, it has to immediately
- *deactivate* the priority level before returning to the |EHF|. See
- `deactivation workflows`_.
-
-.. _non-interrupt-flow:
-
-The following is an example flow for exceptions that targets EL3 other than
-interrupt:
-
-#. The platform provides handlers for the specific kind of exception.
-
-#. The exception arrives, and the corresponding handler is executed.
-
-#. The handler calls ``ehf_activate_priority()`` to activate the required
- priority level. This also has the effect of raising GIC priority mask, thus
- preventing interrupts of lower priority from preempting the handling. The
- handler may choose to do the handling entirely in EL3 or delegate to a lower
- EL.
-
-#. Once exception handling concludes, the handler calls
- ``ehf_deactivate_priority()`` to deactivate the priority level activated
- earlier. This also has the effect of lowering GIC priority mask to what it
- was before.
-
-Interrupt Prioritisation Considerations
----------------------------------------
-
-The GIC priority scheme, by design, prioritises Secure interrupts over Normal
-world ones. The platform further assigns relative priorities amongst Secure
-dispatchers through |EHF|.
-
-As mentioned in `Partitioning priority levels`_, interrupts targeting distinct
-dispatchers fall in distinct priority levels. Because they're routed via the
-GIC, interrupt delivery to the PE is subject to GIC prioritisation rules. In
-particular, when an interrupt is being handled by the PE (i.e., the interrupt is
-in *Active* state), only interrupts of higher priority are signalled to the PE,
-even if interrupts of same or lower priority are pending. This has the side
-effect of one dispatcher being starved of interrupts by virtue of another
-dispatcher handling its (higher priority) interrupts.
-
-The |EHF| doesn't enforce a particular prioritisation policy, but the platform
-should carefully consider the assignment of priorities to dispatchers integrated
-into runtime firmware. The platform should sensibly delineate priority to
-various dispatchers according to their nature. In particular, dispatchers of
-critical nature (RAS, for example) should be assigned higher priority than
-others (SDEI, for example); and within SDEI, Critical priority SDEI should be
-assigned higher priority than Normal ones.
-
-Limitations
------------
-
-The |EHF| has the following limitations:
-
-- Although there could be up to 128 Secure dispatchers supported by the GIC
- priority scheme, the size of descriptor array exposed with
- ``EHF_REGISTER_PRIORITIES()`` macro is currently limited to 32. This serves most
- expected use cases. This may be expanded in the future, should use cases
- demand so.
-
-- The platform must ensure that the priority assigned to the dispatcher in the
- exception descriptor and the programmed priority of interrupts handled by the
- dispatcher match. The |EHF| cannot verify that this has been followed.
-
-----
-
-*Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _Interrupt Framework Design: interrupt-framework-design.rst
-.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
+++ /dev/null
-Trusted Firmware-A design
-=========================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-Trusted Firmware-A (TF-A) implements a subset of the Trusted Board Boot
-Requirements (TBBR) Platform Design Document (PDD) [1]_ for Arm reference
-platforms. The TBB sequence starts when the platform is powered on and runs up
-to the stage where it hands-off control to firmware running in the normal
-world in DRAM. This is the cold boot path.
-
-TF-A also implements the Power State Coordination Interface PDD [2]_ as a
-runtime service. PSCI is the interface from normal world software to firmware
-implementing power management use-cases (for example, secondary CPU boot,
-hotplug and idle). Normal world software can access TF-A runtime services via
-the Arm SMC (Secure Monitor Call) instruction. The SMC instruction must be
-used as mandated by the SMC Calling Convention [3]_.
-
-TF-A implements a framework for configuring and managing interrupts generated
-in either security state. The details of the interrupt management framework
-and its design can be found in TF-A Interrupt Management Design guide [4]_.
-
-TF-A also implements a library for setting up and managing the translation
-tables. The details of this library can be found in `Xlat_tables design`_.
-
-TF-A can be built to support either AArch64 or AArch32 execution state.
-
-Cold boot
----------
-
-The cold boot path starts when the platform is physically turned on. If
-``COLD_BOOT_SINGLE_CPU=0``, one of the CPUs released from reset is chosen as the
-primary CPU, and the remaining CPUs are considered secondary CPUs. The primary
-CPU is chosen through platform-specific means. The cold boot path is mainly
-executed by the primary CPU, other than essential CPU initialization executed by
-all CPUs. The secondary CPUs are kept in a safe platform-specific state until
-the primary CPU has performed enough initialization to boot them.
-
-Refer to the `Reset Design`_ for more information on the effect of the
-``COLD_BOOT_SINGLE_CPU`` platform build option.
-
-The cold boot path in this implementation of TF-A depends on the execution
-state. For AArch64, it is divided into five steps (in order of execution):
-
-- Boot Loader stage 1 (BL1) *AP Trusted ROM*
-- Boot Loader stage 2 (BL2) *Trusted Boot Firmware*
-- Boot Loader stage 3-1 (BL31) *EL3 Runtime Software*
-- Boot Loader stage 3-2 (BL32) *Secure-EL1 Payload* (optional)
-- Boot Loader stage 3-3 (BL33) *Non-trusted Firmware*
-
-For AArch32, it is divided into four steps (in order of execution):
-
-- Boot Loader stage 1 (BL1) *AP Trusted ROM*
-- Boot Loader stage 2 (BL2) *Trusted Boot Firmware*
-- Boot Loader stage 3-2 (BL32) *EL3 Runtime Software*
-- Boot Loader stage 3-3 (BL33) *Non-trusted Firmware*
-
-Arm development platforms (Fixed Virtual Platforms (FVPs) and Juno) implement a
-combination of the following types of memory regions. Each bootloader stage uses
-one or more of these memory regions.
-
-- Regions accessible from both non-secure and secure states. For example,
- non-trusted SRAM, ROM and DRAM.
-- Regions accessible from only the secure state. For example, trusted SRAM and
- ROM. The FVPs also implement the trusted DRAM which is statically
- configured. Additionally, the Base FVPs and Juno development platform
- configure the TrustZone Controller (TZC) to create a region in the DRAM
- which is accessible only from the secure state.
-
-The sections below provide the following details:
-
-- dynamic configuration of Boot Loader stages
-- initialization and execution of the first three stages during cold boot
-- specification of the EL3 Runtime Software (BL31 for AArch64 and BL32 for
- AArch32) entrypoint requirements for use by alternative Trusted Boot
- Firmware in place of the provided BL1 and BL2
-
-Dynamic Configuration during cold boot
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Each of the Boot Loader stages may be dynamically configured if required by the
-platform. The Boot Loader stage may optionally specify a firmware
-configuration file and/or hardware configuration file as listed below:
-
-- HW_CONFIG - The hardware configuration file. Can be shared by all Boot Loader
- stages and also by the Normal World Rich OS.
-- TB_FW_CONFIG - Trusted Boot Firmware configuration file. Shared between BL1
- and BL2.
-- SOC_FW_CONFIG - SoC Firmware configuration file. Used by BL31.
-- TOS_FW_CONFIG - Trusted OS Firmware configuration file. Used by Trusted OS
- (BL32).
-- NT_FW_CONFIG - Non Trusted Firmware configuration file. Used by Non-trusted
- firmware (BL33).
-
-The Arm development platforms use the Flattened Device Tree format for the
-dynamic configuration files.
-
-Each Boot Loader stage can pass up to 4 arguments via registers to the next
-stage. BL2 passes the list of the next images to execute to the *EL3 Runtime
-Software* (BL31 for AArch64 and BL32 for AArch32) via `arg0`. All the other
-arguments are platform defined. The Arm development platforms use the following
-convention:
-
-- BL1 passes the address of a meminfo_t structure to BL2 via ``arg1``. This
- structure contains the memory layout available to BL2.
-- When dynamic configuration files are present, the firmware configuration for
- the next Boot Loader stage is populated in the first available argument and
- the generic hardware configuration is passed the next available argument.
- For example,
-
- - If TB_FW_CONFIG is loaded by BL1, then its address is passed in ``arg0``
- to BL2.
- - If HW_CONFIG is loaded by BL1, then its address is passed in ``arg2`` to
- BL2. Note, ``arg1`` is already used for meminfo_t.
- - If SOC_FW_CONFIG is loaded by BL2, then its address is passed in ``arg1``
- to BL31. Note, ``arg0`` is used to pass the list of executable images.
- - Similarly, if HW_CONFIG is loaded by BL1 or BL2, then its address is
- passed in ``arg2`` to BL31.
- - For other BL3x images, if the firmware configuration file is loaded by
- BL2, then its address is passed in ``arg0`` and if HW_CONFIG is loaded
- then its address is passed in ``arg1``.
-
-BL1
-~~~
-
-This stage begins execution from the platform's reset vector at EL3. The reset
-address is platform dependent but it is usually located in a Trusted ROM area.
-The BL1 data section is copied to trusted SRAM at runtime.
-
-On the Arm development platforms, BL1 code starts execution from the reset
-vector defined by the constant ``BL1_RO_BASE``. The BL1 data section is copied
-to the top of trusted SRAM as defined by the constant ``BL1_RW_BASE``.
-
-The functionality implemented by this stage is as follows.
-
-Determination of boot path
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Whenever a CPU is released from reset, BL1 needs to distinguish between a warm
-boot and a cold boot. This is done using platform-specific mechanisms (see the
-``plat_get_my_entrypoint()`` function in the `Porting Guide`_). In the case of a
-warm boot, a CPU is expected to continue execution from a separate
-entrypoint. In the case of a cold boot, the secondary CPUs are placed in a safe
-platform-specific state (see the ``plat_secondary_cold_boot_setup()`` function in
-the `Porting Guide`_) while the primary CPU executes the remaining cold boot path
-as described in the following sections.
-
-This step only applies when ``PROGRAMMABLE_RESET_ADDRESS=0``. Refer to the
-`Reset Design`_ for more information on the effect of the
-``PROGRAMMABLE_RESET_ADDRESS`` platform build option.
-
-Architectural initialization
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-BL1 performs minimal architectural initialization as follows.
-
-- Exception vectors
-
- BL1 sets up simple exception vectors for both synchronous and asynchronous
- exceptions. The default behavior upon receiving an exception is to populate
- a status code in the general purpose register ``X0/R0`` and call the
- ``plat_report_exception()`` function (see the `Porting Guide`_). The status
- code is one of:
-
- For AArch64:
-
- ::
-
- 0x0 : Synchronous exception from Current EL with SP_EL0
- 0x1 : IRQ exception from Current EL with SP_EL0
- 0x2 : FIQ exception from Current EL with SP_EL0
- 0x3 : System Error exception from Current EL with SP_EL0
- 0x4 : Synchronous exception from Current EL with SP_ELx
- 0x5 : IRQ exception from Current EL with SP_ELx
- 0x6 : FIQ exception from Current EL with SP_ELx
- 0x7 : System Error exception from Current EL with SP_ELx
- 0x8 : Synchronous exception from Lower EL using aarch64
- 0x9 : IRQ exception from Lower EL using aarch64
- 0xa : FIQ exception from Lower EL using aarch64
- 0xb : System Error exception from Lower EL using aarch64
- 0xc : Synchronous exception from Lower EL using aarch32
- 0xd : IRQ exception from Lower EL using aarch32
- 0xe : FIQ exception from Lower EL using aarch32
- 0xf : System Error exception from Lower EL using aarch32
-
- For AArch32:
-
- ::
-
- 0x10 : User mode
- 0x11 : FIQ mode
- 0x12 : IRQ mode
- 0x13 : SVC mode
- 0x16 : Monitor mode
- 0x17 : Abort mode
- 0x1a : Hypervisor mode
- 0x1b : Undefined mode
- 0x1f : System mode
-
- The ``plat_report_exception()`` implementation on the Arm FVP port programs
- the Versatile Express System LED register in the following format to
- indicate the occurrence of an unexpected exception:
-
- ::
-
- SYS_LED[0] - Security state (Secure=0/Non-Secure=1)
- SYS_LED[2:1] - Exception Level (EL3=0x3, EL2=0x2, EL1=0x1, EL0=0x0)
- For AArch32 it is always 0x0
- SYS_LED[7:3] - Exception Class (Sync/Async & origin). This is the value
- of the status code
-
- A write to the LED register reflects in the System LEDs (S6LED0..7) in the
- CLCD window of the FVP.
-
- BL1 does not expect to receive any exceptions other than the SMC exception.
- For the latter, BL1 installs a simple stub. The stub expects to receive a
- limited set of SMC types (determined by their function IDs in the general
- purpose register ``X0/R0``):
-
- - ``BL1_SMC_RUN_IMAGE``: This SMC is raised by BL2 to make BL1 pass control
- to EL3 Runtime Software.
- - All SMCs listed in section "BL1 SMC Interface" in the `Firmware Update`_
- Design Guide are supported for AArch64 only. These SMCs are currently
- not supported when BL1 is built for AArch32.
-
- Any other SMC leads to an assertion failure.
-
-- CPU initialization
-
- BL1 calls the ``reset_handler()`` function which in turn calls the CPU
- specific reset handler function (see the section: "CPU specific operations
- framework").
-
-- Control register setup (for AArch64)
-
- - ``SCTLR_EL3``. Instruction cache is enabled by setting the ``SCTLR_EL3.I``
- bit. Alignment and stack alignment checking is enabled by setting the
- ``SCTLR_EL3.A`` and ``SCTLR_EL3.SA`` bits. Exception endianness is set to
- little-endian by clearing the ``SCTLR_EL3.EE`` bit.
-
- - ``SCR_EL3``. The register width of the next lower exception level is set
- to AArch64 by setting the ``SCR.RW`` bit. The ``SCR.EA`` bit is set to trap
- both External Aborts and SError Interrupts in EL3. The ``SCR.SIF`` bit is
- also set to disable instruction fetches from Non-secure memory when in
- secure state.
-
- - ``CPTR_EL3``. Accesses to the ``CPACR_EL1`` register from EL1 or EL2, or the
- ``CPTR_EL2`` register from EL2 are configured to not trap to EL3 by
- clearing the ``CPTR_EL3.TCPAC`` bit. Access to the trace functionality is
- configured not to trap to EL3 by clearing the ``CPTR_EL3.TTA`` bit.
- Instructions that access the registers associated with Floating Point
- and Advanced SIMD execution are configured to not trap to EL3 by
- clearing the ``CPTR_EL3.TFP`` bit.
-
- - ``DAIF``. The SError interrupt is enabled by clearing the SError interrupt
- mask bit.
-
- - ``MDCR_EL3``. The trap controls, ``MDCR_EL3.TDOSA``, ``MDCR_EL3.TDA`` and
- ``MDCR_EL3.TPM``, are set so that accesses to the registers they control
- do not trap to EL3. AArch64 Secure self-hosted debug is disabled by
- setting the ``MDCR_EL3.SDD`` bit. Also ``MDCR_EL3.SPD32`` is set to
- disable AArch32 Secure self-hosted privileged debug from S-EL1.
-
-- Control register setup (for AArch32)
-
- - ``SCTLR``. Instruction cache is enabled by setting the ``SCTLR.I`` bit.
- Alignment checking is enabled by setting the ``SCTLR.A`` bit.
- Exception endianness is set to little-endian by clearing the
- ``SCTLR.EE`` bit.
-
- - ``SCR``. The ``SCR.SIF`` bit is set to disable instruction fetches from
- Non-secure memory when in secure state.
-
- - ``CPACR``. Allow execution of Advanced SIMD instructions at PL0 and PL1,
- by clearing the ``CPACR.ASEDIS`` bit. Access to the trace functionality
- is configured not to trap to undefined mode by clearing the
- ``CPACR.TRCDIS`` bit.
-
- - ``NSACR``. Enable non-secure access to Advanced SIMD functionality and
- system register access to implemented trace registers.
-
- - ``FPEXC``. Enable access to the Advanced SIMD and floating-point
- functionality from all Exception levels.
-
- - ``CPSR.A``. The Asynchronous data abort interrupt is enabled by clearing
- the Asynchronous data abort interrupt mask bit.
-
- - ``SDCR``. The ``SDCR.SPD`` field is set to disable AArch32 Secure
- self-hosted privileged debug.
-
-Platform initialization
-^^^^^^^^^^^^^^^^^^^^^^^
-
-On Arm platforms, BL1 performs the following platform initializations:
-
-- Enable the Trusted Watchdog.
-- Initialize the console.
-- Configure the Interconnect to enable hardware coherency.
-- Enable the MMU and map the memory it needs to access.
-- Configure any required platform storage to load the next bootloader image
- (BL2).
-- If the BL1 dynamic configuration file, ``TB_FW_CONFIG``, is available, then
- load it to the platform defined address and make it available to BL2 via
- ``arg0``.
-- Configure the system timer and program the `CNTFRQ_EL0` for use by NS-BL1U
- and NS-BL2U firmware update images.
-
-Firmware Update detection and execution
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-After performing platform setup, BL1 common code calls
-``bl1_plat_get_next_image_id()`` to determine if `Firmware Update`_ is required or
-to proceed with the normal boot process. If the platform code returns
-``BL2_IMAGE_ID`` then the normal boot sequence is executed as described in the
-next section, else BL1 assumes that `Firmware Update`_ is required and execution
-passes to the first image in the `Firmware Update`_ process. In either case, BL1
-retrieves a descriptor of the next image by calling ``bl1_plat_get_image_desc()``.
-The image descriptor contains an ``entry_point_info_t`` structure, which BL1
-uses to initialize the execution state of the next image.
-
-BL2 image load and execution
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-In the normal boot flow, BL1 execution continues as follows:
-
-#. BL1 prints the following string from the primary CPU to indicate successful
- execution of the BL1 stage:
-
- ::
-
- "Booting Trusted Firmware"
-
-#. BL1 loads a BL2 raw binary image from platform storage, at a
- platform-specific base address. Prior to the load, BL1 invokes
- ``bl1_plat_handle_pre_image_load()`` which allows the platform to update or
- use the image information. If the BL2 image file is not present or if
- there is not enough free trusted SRAM the following error message is
- printed:
-
- ::
-
- "Failed to load BL2 firmware."
-
-#. BL1 invokes ``bl1_plat_handle_post_image_load()`` which again is intended
- for platforms to take further action after image load. This function must
- populate the necessary arguments for BL2, which may also include the memory
- layout. Further description of the memory layout can be found later
- in this document.
-
-#. BL1 passes control to the BL2 image at Secure EL1 (for AArch64) or at
- Secure SVC mode (for AArch32), starting from its load address.
-
-BL2
-~~~
-
-BL1 loads and passes control to BL2 at Secure-EL1 (for AArch64) or at Secure
-SVC mode (for AArch32) . BL2 is linked against and loaded at a platform-specific
-base address (more information can be found later in this document).
-The functionality implemented by BL2 is as follows.
-
-Architectural initialization
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-For AArch64, BL2 performs the minimal architectural initialization required
-for subsequent stages of TF-A and normal world software. EL1 and EL0 are given
-access to Floating Point and Advanced SIMD registers by clearing the
-``CPACR.FPEN`` bits.
-
-For AArch32, the minimal architectural initialization required for subsequent
-stages of TF-A and normal world software is taken care of in BL1 as both BL1
-and BL2 execute at PL1.
-
-Platform initialization
-^^^^^^^^^^^^^^^^^^^^^^^
-
-On Arm platforms, BL2 performs the following platform initializations:
-
-- Initialize the console.
-- Configure any required platform storage to allow loading further bootloader
- images.
-- Enable the MMU and map the memory it needs to access.
-- Perform platform security setup to allow access to controlled components.
-- Reserve some memory for passing information to the next bootloader image
- EL3 Runtime Software and populate it.
-- Define the extents of memory available for loading each subsequent
- bootloader image.
-- If BL1 has passed TB_FW_CONFIG dynamic configuration file in ``arg0``,
- then parse it.
-
-Image loading in BL2
-^^^^^^^^^^^^^^^^^^^^
-
-BL2 generic code loads the images based on the list of loadable images
-provided by the platform. BL2 passes the list of executable images
-provided by the platform to the next handover BL image.
-
-The list of loadable images provided by the platform may also contain
-dynamic configuration files. The files are loaded and can be parsed as
-needed in the ``bl2_plat_handle_post_image_load()`` function. These
-configuration files can be passed to next Boot Loader stages as arguments
-by updating the corresponding entrypoint information in this function.
-
-SCP_BL2 (System Control Processor Firmware) image load
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Some systems have a separate System Control Processor (SCP) for power, clock,
-reset and system control. BL2 loads the optional SCP_BL2 image from platform
-storage into a platform-specific region of secure memory. The subsequent
-handling of SCP_BL2 is platform specific. For example, on the Juno Arm
-development platform port the image is transferred into SCP's internal memory
-using the Boot Over MHU (BOM) protocol after being loaded in the trusted SRAM
-memory. The SCP executes SCP_BL2 and signals to the Application Processor (AP)
-for BL2 execution to continue.
-
-EL3 Runtime Software image load
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-BL2 loads the EL3 Runtime Software image from platform storage into a platform-
-specific address in trusted SRAM. If there is not enough memory to load the
-image or image is missing it leads to an assertion failure.
-
-AArch64 BL32 (Secure-EL1 Payload) image load
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-BL2 loads the optional BL32 image from platform storage into a platform-
-specific region of secure memory. The image executes in the secure world. BL2
-relies on BL31 to pass control to the BL32 image, if present. Hence, BL2
-populates a platform-specific area of memory with the entrypoint/load-address
-of the BL32 image. The value of the Saved Processor Status Register (``SPSR``)
-for entry into BL32 is not determined by BL2, it is initialized by the
-Secure-EL1 Payload Dispatcher (see later) within BL31, which is responsible for
-managing interaction with BL32. This information is passed to BL31.
-
-BL33 (Non-trusted Firmware) image load
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-BL2 loads the BL33 image (e.g. UEFI or other test or boot software) from
-platform storage into non-secure memory as defined by the platform.
-
-BL2 relies on EL3 Runtime Software to pass control to BL33 once secure state
-initialization is complete. Hence, BL2 populates a platform-specific area of
-memory with the entrypoint and Saved Program Status Register (``SPSR``) of the
-normal world software image. The entrypoint is the load address of the BL33
-image. The ``SPSR`` is determined as specified in Section 5.13 of the
-`PSCI PDD`_. This information is passed to the EL3 Runtime Software.
-
-AArch64 BL31 (EL3 Runtime Software) execution
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-BL2 execution continues as follows:
-
-#. BL2 passes control back to BL1 by raising an SMC, providing BL1 with the
- BL31 entrypoint. The exception is handled by the SMC exception handler
- installed by BL1.
-
-#. BL1 turns off the MMU and flushes the caches. It clears the
- ``SCTLR_EL3.M/I/C`` bits, flushes the data cache to the point of coherency
- and invalidates the TLBs.
-
-#. BL1 passes control to BL31 at the specified entrypoint at EL3.
-
-Running BL2 at EL3 execution level
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Some platforms have a non-TF-A Boot ROM that expects the next boot stage
-to execute at EL3. On these platforms, TF-A BL1 is a waste of memory
-as its only purpose is to ensure TF-A BL2 is entered at S-EL1. To avoid
-this waste, a special mode enables BL2 to execute at EL3, which allows
-a non-TF-A Boot ROM to load and jump directly to BL2. This mode is selected
-when the build flag BL2_AT_EL3 is enabled. The main differences in this
-mode are:
-
-#. BL2 includes the reset code and the mailbox mechanism to differentiate
- cold boot and warm boot. It runs at EL3 doing the arch
- initialization required for EL3.
-
-#. BL2 does not receive the meminfo information from BL1 anymore. This
- information can be passed by the Boot ROM or be internal to the
- BL2 image.
-
-#. Since BL2 executes at EL3, BL2 jumps directly to the next image,
- instead of invoking the RUN_IMAGE SMC call.
-
-
-We assume 3 different types of BootROM support on the platform:
-
-#. The Boot ROM always jumps to the same address, for both cold
- and warm boot. In this case, we will need to keep a resident part
- of BL2 whose memory cannot be reclaimed by any other image. The
- linker script defines the symbols __TEXT_RESIDENT_START__ and
- __TEXT_RESIDENT_END__ that allows the platform to configure
- correctly the memory map.
-#. The platform has some mechanism to indicate the jump address to the
- Boot ROM. Platform code can then program the jump address with
- psci_warmboot_entrypoint during cold boot.
-#. The platform has some mechanism to program the reset address using
- the PROGRAMMABLE_RESET_ADDRESS feature. Platform code can then
- program the reset address with psci_warmboot_entrypoint during
- cold boot, bypassing the boot ROM for warm boot.
-
-In the last 2 cases, no part of BL2 needs to remain resident at
-runtime. In the first 2 cases, we expect the Boot ROM to be able to
-differentiate between warm and cold boot, to avoid loading BL2 again
-during warm boot.
-
-This functionality can be tested with FVP loading the image directly
-in memory and changing the address where the system jumps at reset.
-For example:
-
- -C cluster0.cpu0.RVBAR=0x4022000
- --data cluster0.cpu0=bl2.bin@0x4022000
-
-With this configuration, FVP is like a platform of the first case,
-where the Boot ROM jumps always to the same address. For simplification,
-BL32 is loaded in DRAM in this case, to avoid other images reclaiming
-BL2 memory.
-
-
-AArch64 BL31
-~~~~~~~~~~~~
-
-The image for this stage is loaded by BL2 and BL1 passes control to BL31 at
-EL3. BL31 executes solely in trusted SRAM. BL31 is linked against and
-loaded at a platform-specific base address (more information can be found later
-in this document). The functionality implemented by BL31 is as follows.
-
-Architectural initialization
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Currently, BL31 performs a similar architectural initialization to BL1 as
-far as system register settings are concerned. Since BL1 code resides in ROM,
-architectural initialization in BL31 allows override of any previous
-initialization done by BL1.
-
-BL31 initializes the per-CPU data framework, which provides a cache of
-frequently accessed per-CPU data optimised for fast, concurrent manipulation
-on different CPUs. This buffer includes pointers to per-CPU contexts, crash
-buffer, CPU reset and power down operations, PSCI data, platform data and so on.
-
-It then replaces the exception vectors populated by BL1 with its own. BL31
-exception vectors implement more elaborate support for handling SMCs since this
-is the only mechanism to access the runtime services implemented by BL31 (PSCI
-for example). BL31 checks each SMC for validity as specified by the
-`SMC calling convention PDD`_ before passing control to the required SMC
-handler routine.
-
-BL31 programs the ``CNTFRQ_EL0`` register with the clock frequency of the system
-counter, which is provided by the platform.
-
-Platform initialization
-^^^^^^^^^^^^^^^^^^^^^^^
-
-BL31 performs detailed platform initialization, which enables normal world
-software to function correctly.
-
-On Arm platforms, this consists of the following:
-
-- Initialize the console.
-- Configure the Interconnect to enable hardware coherency.
-- Enable the MMU and map the memory it needs to access.
-- Initialize the generic interrupt controller.
-- Initialize the power controller device.
-- Detect the system topology.
-
-Runtime services initialization
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-BL31 is responsible for initializing the runtime services. One of them is PSCI.
-
-As part of the PSCI initializations, BL31 detects the system topology. It also
-initializes the data structures that implement the state machine used to track
-the state of power domain nodes. The state can be one of ``OFF``, ``RUN`` or
-``RETENTION``. All secondary CPUs are initially in the ``OFF`` state. The cluster
-that the primary CPU belongs to is ``ON``; any other cluster is ``OFF``. It also
-initializes the locks that protect them. BL31 accesses the state of a CPU or
-cluster immediately after reset and before the data cache is enabled in the
-warm boot path. It is not currently possible to use 'exclusive' based spinlocks,
-therefore BL31 uses locks based on Lamport's Bakery algorithm instead.
-
-The runtime service framework and its initialization is described in more
-detail in the "EL3 runtime services framework" section below.
-
-Details about the status of the PSCI implementation are provided in the
-"Power State Coordination Interface" section below.
-
-AArch64 BL32 (Secure-EL1 Payload) image initialization
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If a BL32 image is present then there must be a matching Secure-EL1 Payload
-Dispatcher (SPD) service (see later for details). During initialization
-that service must register a function to carry out initialization of BL32
-once the runtime services are fully initialized. BL31 invokes such a
-registered function to initialize BL32 before running BL33. This initialization
-is not necessary for AArch32 SPs.
-
-Details on BL32 initialization and the SPD's role are described in the
-"Secure-EL1 Payloads and Dispatchers" section below.
-
-BL33 (Non-trusted Firmware) execution
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-EL3 Runtime Software initializes the EL2 or EL1 processor context for normal-
-world cold boot, ensuring that no secure state information finds its way into
-the non-secure execution state. EL3 Runtime Software uses the entrypoint
-information provided by BL2 to jump to the Non-trusted firmware image (BL33)
-at the highest available Exception Level (EL2 if available, otherwise EL1).
-
-Using alternative Trusted Boot Firmware in place of BL1 & BL2 (AArch64 only)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Some platforms have existing implementations of Trusted Boot Firmware that
-would like to use TF-A BL31 for the EL3 Runtime Software. To enable this
-firmware architecture it is important to provide a fully documented and stable
-interface between the Trusted Boot Firmware and BL31.
-
-Future changes to the BL31 interface will be done in a backwards compatible
-way, and this enables these firmware components to be independently enhanced/
-updated to develop and exploit new functionality.
-
-Required CPU state when calling ``bl31_entrypoint()`` during cold boot
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This function must only be called by the primary CPU.
-
-On entry to this function the calling primary CPU must be executing in AArch64
-EL3, little-endian data access, and all interrupt sources masked:
-
-::
-
- PSTATE.EL = 3
- PSTATE.RW = 1
- PSTATE.DAIF = 0xf
- SCTLR_EL3.EE = 0
-
-X0 and X1 can be used to pass information from the Trusted Boot Firmware to the
-platform code in BL31:
-
-::
-
- X0 : Reserved for common TF-A information
- X1 : Platform specific information
-
-BL31 zero-init sections (e.g. ``.bss``) should not contain valid data on entry,
-these will be zero filled prior to invoking platform setup code.
-
-Use of the X0 and X1 parameters
-'''''''''''''''''''''''''''''''
-
-The parameters are platform specific and passed from ``bl31_entrypoint()`` to
-``bl31_early_platform_setup()``. The value of these parameters is never directly
-used by the common BL31 code.
-
-The convention is that ``X0`` conveys information regarding the BL31, BL32 and
-BL33 images from the Trusted Boot firmware and ``X1`` can be used for other
-platform specific purpose. This convention allows platforms which use TF-A's
-BL1 and BL2 images to transfer additional platform specific information from
-Secure Boot without conflicting with future evolution of TF-A using ``X0`` to
-pass a ``bl31_params`` structure.
-
-BL31 common and SPD initialization code depends on image and entrypoint
-information about BL33 and BL32, which is provided via BL31 platform APIs.
-This information is required until the start of execution of BL33. This
-information can be provided in a platform defined manner, e.g. compiled into
-the platform code in BL31, or provided in a platform defined memory location
-by the Trusted Boot firmware, or passed from the Trusted Boot Firmware via the
-Cold boot Initialization parameters. This data may need to be cleaned out of
-the CPU caches if it is provided by an earlier boot stage and then accessed by
-BL31 platform code before the caches are enabled.
-
-TF-A's BL2 implementation passes a ``bl31_params`` structure in
-``X0`` and the Arm development platforms interpret this in the BL31 platform
-code.
-
-MMU, Data caches & Coherency
-''''''''''''''''''''''''''''
-
-BL31 does not depend on the enabled state of the MMU, data caches or
-interconnect coherency on entry to ``bl31_entrypoint()``. If these are disabled
-on entry, these should be enabled during ``bl31_plat_arch_setup()``.
-
-Data structures used in the BL31 cold boot interface
-''''''''''''''''''''''''''''''''''''''''''''''''''''
-
-These structures are designed to support compatibility and independent
-evolution of the structures and the firmware images. For example, a version of
-BL31 that can interpret the BL3x image information from different versions of
-BL2, a platform that uses an extended entry_point_info structure to convey
-additional register information to BL31, or a ELF image loader that can convey
-more details about the firmware images.
-
-To support these scenarios the structures are versioned and sized, which enables
-BL31 to detect which information is present and respond appropriately. The
-``param_header`` is defined to capture this information:
-
-.. code:: c
-
- typedef struct param_header {
- uint8_t type; /* type of the structure */
- uint8_t version; /* version of this structure */
- uint16_t size; /* size of this structure in bytes */
- uint32_t attr; /* attributes: unused bits SBZ */
- } param_header_t;
-
-The structures using this format are ``entry_point_info``, ``image_info`` and
-``bl31_params``. The code that allocates and populates these structures must set
-the header fields appropriately, and the ``SET_PARAM_HEAD()`` a macro is defined
-to simplify this action.
-
-Required CPU state for BL31 Warm boot initialization
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-When requesting a CPU power-on, or suspending a running CPU, TF-A provides
-the platform power management code with a Warm boot initialization
-entry-point, to be invoked by the CPU immediately after the reset handler.
-On entry to the Warm boot initialization function the calling CPU must be in
-AArch64 EL3, little-endian data access and all interrupt sources masked:
-
-::
-
- PSTATE.EL = 3
- PSTATE.RW = 1
- PSTATE.DAIF = 0xf
- SCTLR_EL3.EE = 0
-
-The PSCI implementation will initialize the processor state and ensure that the
-platform power management code is then invoked as required to initialize all
-necessary system, cluster and CPU resources.
-
-AArch32 EL3 Runtime Software entrypoint interface
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To enable this firmware architecture it is important to provide a fully
-documented and stable interface between the Trusted Boot Firmware and the
-AArch32 EL3 Runtime Software.
-
-Future changes to the entrypoint interface will be done in a backwards
-compatible way, and this enables these firmware components to be independently
-enhanced/updated to develop and exploit new functionality.
-
-Required CPU state when entering during cold boot
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This function must only be called by the primary CPU.
-
-On entry to this function the calling primary CPU must be executing in AArch32
-EL3, little-endian data access, and all interrupt sources masked:
-
-::
-
- PSTATE.AIF = 0x7
- SCTLR.EE = 0
-
-R0 and R1 are used to pass information from the Trusted Boot Firmware to the
-platform code in AArch32 EL3 Runtime Software:
-
-::
-
- R0 : Reserved for common TF-A information
- R1 : Platform specific information
-
-Use of the R0 and R1 parameters
-'''''''''''''''''''''''''''''''
-
-The parameters are platform specific and the convention is that ``R0`` conveys
-information regarding the BL3x images from the Trusted Boot firmware and ``R1``
-can be used for other platform specific purpose. This convention allows
-platforms which use TF-A's BL1 and BL2 images to transfer additional platform
-specific information from Secure Boot without conflicting with future
-evolution of TF-A using ``R0`` to pass a ``bl_params`` structure.
-
-The AArch32 EL3 Runtime Software is responsible for entry into BL33. This
-information can be obtained in a platform defined manner, e.g. compiled into
-the AArch32 EL3 Runtime Software, or provided in a platform defined memory
-location by the Trusted Boot firmware, or passed from the Trusted Boot Firmware
-via the Cold boot Initialization parameters. This data may need to be cleaned
-out of the CPU caches if it is provided by an earlier boot stage and then
-accessed by AArch32 EL3 Runtime Software before the caches are enabled.
-
-When using AArch32 EL3 Runtime Software, the Arm development platforms pass a
-``bl_params`` structure in ``R0`` from BL2 to be interpreted by AArch32 EL3 Runtime
-Software platform code.
-
-MMU, Data caches & Coherency
-''''''''''''''''''''''''''''
-
-AArch32 EL3 Runtime Software must not depend on the enabled state of the MMU,
-data caches or interconnect coherency in its entrypoint. They must be explicitly
-enabled if required.
-
-Data structures used in cold boot interface
-'''''''''''''''''''''''''''''''''''''''''''
-
-The AArch32 EL3 Runtime Software cold boot interface uses ``bl_params`` instead
-of ``bl31_params``. The ``bl_params`` structure is based on the convention
-described in AArch64 BL31 cold boot interface section.
-
-Required CPU state for warm boot initialization
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-When requesting a CPU power-on, or suspending a running CPU, AArch32 EL3
-Runtime Software must ensure execution of a warm boot initialization entrypoint.
-If TF-A BL1 is used and the PROGRAMMABLE_RESET_ADDRESS build flag is false,
-then AArch32 EL3 Runtime Software must ensure that BL1 branches to the warm
-boot entrypoint by arranging for the BL1 platform function,
-plat_get_my_entrypoint(), to return a non-zero value.
-
-In this case, the warm boot entrypoint must be in AArch32 EL3, little-endian
-data access and all interrupt sources masked:
-
-::
-
- PSTATE.AIF = 0x7
- SCTLR.EE = 0
-
-The warm boot entrypoint may be implemented by using TF-A
-``psci_warmboot_entrypoint()`` function. In that case, the platform must fulfil
-the pre-requisites mentioned in the `PSCI Library integration guide`_.
-
-EL3 runtime services framework
-------------------------------
-
-Software executing in the non-secure state and in the secure state at exception
-levels lower than EL3 will request runtime services using the Secure Monitor
-Call (SMC) instruction. These requests will follow the convention described in
-the SMC Calling Convention PDD (`SMCCC`_). The `SMCCC`_ assigns function
-identifiers to each SMC request and describes how arguments are passed and
-returned.
-
-The EL3 runtime services framework enables the development of services by
-different providers that can be easily integrated into final product firmware.
-The following sections describe the framework which facilitates the
-registration, initialization and use of runtime services in EL3 Runtime
-Software (BL31).
-
-The design of the runtime services depends heavily on the concepts and
-definitions described in the `SMCCC`_, in particular SMC Function IDs, Owning
-Entity Numbers (OEN), Fast and Yielding calls, and the SMC32 and SMC64 calling
-conventions. Please refer to that document for more detailed explanation of
-these terms.
-
-The following runtime services are expected to be implemented first. They have
-not all been instantiated in the current implementation.
-
-#. Standard service calls
-
- This service is for management of the entire system. The Power State
- Coordination Interface (`PSCI`_) is the first set of standard service calls
- defined by Arm (see PSCI section later).
-
-#. Secure-EL1 Payload Dispatcher service
-
- If a system runs a Trusted OS or other Secure-EL1 Payload (SP) then
- it also requires a *Secure Monitor* at EL3 to switch the EL1 processor
- context between the normal world (EL1/EL2) and trusted world (Secure-EL1).
- The Secure Monitor will make these world switches in response to SMCs. The
- `SMCCC`_ provides for such SMCs with the Trusted OS Call and Trusted
- Application Call OEN ranges.
-
- The interface between the EL3 Runtime Software and the Secure-EL1 Payload is
- not defined by the `SMCCC`_ or any other standard. As a result, each
- Secure-EL1 Payload requires a specific Secure Monitor that runs as a runtime
- service - within TF-A this service is referred to as the Secure-EL1 Payload
- Dispatcher (SPD).
-
- TF-A provides a Test Secure-EL1 Payload (TSP) and its associated Dispatcher
- (TSPD). Details of SPD design and TSP/TSPD operation are described in the
- "Secure-EL1 Payloads and Dispatchers" section below.
-
-#. CPU implementation service
-
- This service will provide an interface to CPU implementation specific
- services for a given platform e.g. access to processor errata workarounds.
- This service is currently unimplemented.
-
-Additional services for Arm Architecture, SiP and OEM calls can be implemented.
-Each implemented service handles a range of SMC function identifiers as
-described in the `SMCCC`_.
-
-Registration
-~~~~~~~~~~~~
-
-A runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying
-the name of the service, the range of OENs covered, the type of service and
-initialization and call handler functions. This macro instantiates a ``const struct rt_svc_desc`` for the service with these details (see ``runtime_svc.h``).
-This structure is allocated in a special ELF section ``rt_svc_descs``, enabling
-the framework to find all service descriptors included into BL31.
-
-The specific service for a SMC Function is selected based on the OEN and call
-type of the Function ID, and the framework uses that information in the service
-descriptor to identify the handler for the SMC Call.
-
-The service descriptors do not include information to identify the precise set
-of SMC function identifiers supported by this service implementation, the
-security state from which such calls are valid nor the capability to support
-64-bit and/or 32-bit callers (using SMC32 or SMC64). Responding appropriately
-to these aspects of a SMC call is the responsibility of the service
-implementation, the framework is focused on integration of services from
-different providers and minimizing the time taken by the framework before the
-service handler is invoked.
-
-Details of the parameters, requirements and behavior of the initialization and
-call handling functions are provided in the following sections.
-
-Initialization
-~~~~~~~~~~~~~~
-
-``runtime_svc_init()`` in ``runtime_svc.c`` initializes the runtime services
-framework running on the primary CPU during cold boot as part of the BL31
-initialization. This happens prior to initializing a Trusted OS and running
-Normal world boot firmware that might in turn use these services.
-Initialization involves validating each of the declared runtime service
-descriptors, calling the service initialization function and populating the
-index used for runtime lookup of the service.
-
-The BL31 linker script collects all of the declared service descriptors into a
-single array and defines symbols that allow the framework to locate and traverse
-the array, and determine its size.
-
-The framework does basic validation of each descriptor to halt firmware
-initialization if service declaration errors are detected. The framework does
-not check descriptors for the following error conditions, and may behave in an
-unpredictable manner under such scenarios:
-
-#. Overlapping OEN ranges
-#. Multiple descriptors for the same range of OENs and ``call_type``
-#. Incorrect range of owning entity numbers for a given ``call_type``
-
-Once validated, the service ``init()`` callback is invoked. This function carries
-out any essential EL3 initialization before servicing requests. The ``init()``
-function is only invoked on the primary CPU during cold boot. If the service
-uses per-CPU data this must either be initialized for all CPUs during this call,
-or be done lazily when a CPU first issues an SMC call to that service. If
-``init()`` returns anything other than ``0``, this is treated as an initialization
-error and the service is ignored: this does not cause the firmware to halt.
-
-The OEN and call type fields present in the SMC Function ID cover a total of
-128 distinct services, but in practice a single descriptor can cover a range of
-OENs, e.g. SMCs to call a Trusted OS function. To optimize the lookup of a
-service handler, the framework uses an array of 128 indices that map every
-distinct OEN/call-type combination either to one of the declared services or to
-indicate the service is not handled. This ``rt_svc_descs_indices[]`` array is
-populated for all of the OENs covered by a service after the service ``init()``
-function has reported success. So a service that fails to initialize will never
-have it's ``handle()`` function invoked.
-
-The following figure shows how the ``rt_svc_descs_indices[]`` index maps the SMC
-Function ID call type and OEN onto a specific service handler in the
-``rt_svc_descs[]`` array.
-
-|Image 1|
-
-Handling an SMC
-~~~~~~~~~~~~~~~
-
-When the EL3 runtime services framework receives a Secure Monitor Call, the SMC
-Function ID is passed in W0 from the lower exception level (as per the
-`SMCCC`_). If the calling register width is AArch32, it is invalid to invoke an
-SMC Function which indicates the SMC64 calling convention: such calls are
-ignored and return the Unknown SMC Function Identifier result code ``0xFFFFFFFF``
-in R0/X0.
-
-Bit[31] (fast/yielding call) and bits[29:24] (owning entity number) of the SMC
-Function ID are combined to index into the ``rt_svc_descs_indices[]`` array. The
-resulting value might indicate a service that has no handler, in this case the
-framework will also report an Unknown SMC Function ID. Otherwise, the value is
-used as a further index into the ``rt_svc_descs[]`` array to locate the required
-service and handler.
-
-The service's ``handle()`` callback is provided with five of the SMC parameters
-directly, the others are saved into memory for retrieval (if needed) by the
-handler. The handler is also provided with an opaque ``handle`` for use with the
-supporting library for parameter retrieval, setting return values and context
-manipulation; and with ``flags`` indicating the security state of the caller. The
-framework finally sets up the execution stack for the handler, and invokes the
-services ``handle()`` function.
-
-On return from the handler the result registers are populated in X0-X3 before
-restoring the stack and CPU state and returning from the original SMC.
-
-Exception Handling Framework
-----------------------------
-
-Please refer to the `Exception Handling Framework`_ document.
-
-Power State Coordination Interface
-----------------------------------
-
-TODO: Provide design walkthrough of PSCI implementation.
-
-The PSCI v1.1 specification categorizes APIs as optional and mandatory. All the
-mandatory APIs in PSCI v1.1, PSCI v1.0 and in PSCI v0.2 draft specification
-`Power State Coordination Interface PDD`_ are implemented. The table lists
-the PSCI v1.1 APIs and their support in generic code.
-
-An API implementation might have a dependency on platform code e.g. CPU_SUSPEND
-requires the platform to export a part of the implementation. Hence the level
-of support of the mandatory APIs depends upon the support exported by the
-platform port as well. The Juno and FVP (all variants) platforms export all the
-required support.
-
-+-----------------------------+-------------+-------------------------------+
-| PSCI v1.1 API | Supported | Comments |
-+=============================+=============+===============================+
-| ``PSCI_VERSION`` | Yes | The version returned is 1.1 |
-+-----------------------------+-------------+-------------------------------+
-| ``CPU_SUSPEND`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``CPU_OFF`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``CPU_ON`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``AFFINITY_INFO`` | Yes | |
-+-----------------------------+-------------+-------------------------------+
-| ``MIGRATE`` | Yes\*\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``MIGRATE_INFO_TYPE`` | Yes\*\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``MIGRATE_INFO_CPU`` | Yes\*\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``SYSTEM_OFF`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``SYSTEM_RESET`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``PSCI_FEATURES`` | Yes | |
-+-----------------------------+-------------+-------------------------------+
-| ``CPU_FREEZE`` | No | |
-+-----------------------------+-------------+-------------------------------+
-| ``CPU_DEFAULT_SUSPEND`` | No | |
-+-----------------------------+-------------+-------------------------------+
-| ``NODE_HW_STATE`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``SYSTEM_SUSPEND`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``PSCI_SET_SUSPEND_MODE`` | No | |
-+-----------------------------+-------------+-------------------------------+
-| ``PSCI_STAT_RESIDENCY`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``PSCI_STAT_COUNT`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``SYSTEM_RESET2`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``MEM_PROTECT`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-| ``MEM_PROTECT_CHECK_RANGE`` | Yes\* | |
-+-----------------------------+-------------+-------------------------------+
-
-\*Note : These PSCI APIs require platform power management hooks to be
-registered with the generic PSCI code to be supported.
-
-\*\*Note : These PSCI APIs require appropriate Secure Payload Dispatcher
-hooks to be registered with the generic PSCI code to be supported.
-
-The PSCI implementation in TF-A is a library which can be integrated with
-AArch64 or AArch32 EL3 Runtime Software for Armv8-A systems. A guide to
-integrating PSCI library with AArch32 EL3 Runtime Software can be found
-`here`_.
-
-Secure-EL1 Payloads and Dispatchers
------------------------------------
-
-On a production system that includes a Trusted OS running in Secure-EL1/EL0,
-the Trusted OS is coupled with a companion runtime service in the BL31
-firmware. This service is responsible for the initialisation of the Trusted
-OS and all communications with it. The Trusted OS is the BL32 stage of the
-boot flow in TF-A. The firmware will attempt to locate, load and execute a
-BL32 image.
-
-TF-A uses a more general term for the BL32 software that runs at Secure-EL1 -
-the *Secure-EL1 Payload* - as it is not always a Trusted OS.
-
-TF-A provides a Test Secure-EL1 Payload (TSP) and a Test Secure-EL1 Payload
-Dispatcher (TSPD) service as an example of how a Trusted OS is supported on a
-production system using the Runtime Services Framework. On such a system, the
-Test BL32 image and service are replaced by the Trusted OS and its dispatcher
-service. The TF-A build system expects that the dispatcher will define the
-build flag ``NEED_BL32`` to enable it to include the BL32 in the build either
-as a binary or to compile from source depending on whether the ``BL32`` build
-option is specified or not.
-
-The TSP runs in Secure-EL1. It is designed to demonstrate synchronous
-communication with the normal-world software running in EL1/EL2. Communication
-is initiated by the normal-world software
-
-- either directly through a Fast SMC (as defined in the `SMCCC`_)
-
-- or indirectly through a `PSCI`_ SMC. The `PSCI`_ implementation in turn
- informs the TSPD about the requested power management operation. This allows
- the TSP to prepare for or respond to the power state change
-
-The TSPD service is responsible for.
-
-- Initializing the TSP
-
-- Routing requests and responses between the secure and the non-secure
- states during the two types of communications just described
-
-Initializing a BL32 Image
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Secure-EL1 Payload Dispatcher (SPD) service is responsible for initializing
-the BL32 image. It needs access to the information passed by BL2 to BL31 to do
-so. This is provided by:
-
-.. code:: c
-
- entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t);
-
-which returns a reference to the ``entry_point_info`` structure corresponding to
-the image which will be run in the specified security state. The SPD uses this
-API to get entry point information for the SECURE image, BL32.
-
-In the absence of a BL32 image, BL31 passes control to the normal world
-bootloader image (BL33). When the BL32 image is present, it is typical
-that the SPD wants control to be passed to BL32 first and then later to BL33.
-
-To do this the SPD has to register a BL32 initialization function during
-initialization of the SPD service. The BL32 initialization function has this
-prototype:
-
-.. code:: c
-
- int32_t init(void);
-
-and is registered using the ``bl31_register_bl32_init()`` function.
-
-TF-A supports two approaches for the SPD to pass control to BL32 before
-returning through EL3 and running the non-trusted firmware (BL33):
-
-#. In the BL32 setup function, use ``bl31_set_next_image_type()`` to
- request that the exit from ``bl31_main()`` is to the BL32 entrypoint in
- Secure-EL1. BL31 will exit to BL32 using the asynchronous method by
- calling ``bl31_prepare_next_image_entry()`` and ``el3_exit()``.
-
- When the BL32 has completed initialization at Secure-EL1, it returns to
- BL31 by issuing an SMC, using a Function ID allocated to the SPD. On
- receipt of this SMC, the SPD service handler should switch the CPU context
- from trusted to normal world and use the ``bl31_set_next_image_type()`` and
- ``bl31_prepare_next_image_entry()`` functions to set up the initial return to
- the normal world firmware BL33. On return from the handler the framework
- will exit to EL2 and run BL33.
-
-#. The BL32 setup function registers an initialization function using
- ``bl31_register_bl32_init()`` which provides a SPD-defined mechanism to
- invoke a 'world-switch synchronous call' to Secure-EL1 to run the BL32
- entrypoint.
- NOTE: The Test SPD service included with TF-A provides one implementation
- of such a mechanism.
-
- On completion BL32 returns control to BL31 via a SMC, and on receipt the
- SPD service handler invokes the synchronous call return mechanism to return
- to the BL32 initialization function. On return from this function,
- ``bl31_main()`` will set up the return to the normal world firmware BL33 and
- continue the boot process in the normal world.
-
-Crash Reporting in BL31
------------------------
-
-BL31 implements a scheme for reporting the processor state when an unhandled
-exception is encountered. The reporting mechanism attempts to preserve all the
-register contents and report it via a dedicated UART (PL011 console). BL31
-reports the general purpose, EL3, Secure EL1 and some EL2 state registers.
-
-A dedicated per-CPU crash stack is maintained by BL31 and this is retrieved via
-the per-CPU pointer cache. The implementation attempts to minimise the memory
-required for this feature. The file ``crash_reporting.S`` contains the
-implementation for crash reporting.
-
-The sample crash output is shown below.
-
-::
-
- x0 :0x000000004F00007C
- x1 :0x0000000007FFFFFF
- x2 :0x0000000004014D50
- x3 :0x0000000000000000
- x4 :0x0000000088007998
- x5 :0x00000000001343AC
- x6 :0x0000000000000016
- x7 :0x00000000000B8A38
- x8 :0x00000000001343AC
- x9 :0x00000000000101A8
- x10 :0x0000000000000002
- x11 :0x000000000000011C
- x12 :0x00000000FEFDC644
- x13 :0x00000000FED93FFC
- x14 :0x0000000000247950
- x15 :0x00000000000007A2
- x16 :0x00000000000007A4
- x17 :0x0000000000247950
- x18 :0x0000000000000000
- x19 :0x00000000FFFFFFFF
- x20 :0x0000000004014D50
- x21 :0x000000000400A38C
- x22 :0x0000000000247950
- x23 :0x0000000000000010
- x24 :0x0000000000000024
- x25 :0x00000000FEFDC868
- x26 :0x00000000FEFDC86A
- x27 :0x00000000019EDEDC
- x28 :0x000000000A7CFDAA
- x29 :0x0000000004010780
- x30 :0x000000000400F004
- scr_el3 :0x0000000000000D3D
- sctlr_el3 :0x0000000000C8181F
- cptr_el3 :0x0000000000000000
- tcr_el3 :0x0000000080803520
- daif :0x00000000000003C0
- mair_el3 :0x00000000000004FF
- spsr_el3 :0x00000000800003CC
- elr_el3 :0x000000000400C0CC
- ttbr0_el3 :0x00000000040172A0
- esr_el3 :0x0000000096000210
- sp_el3 :0x0000000004014D50
- far_el3 :0x000000004F00007C
- spsr_el1 :0x0000000000000000
- elr_el1 :0x0000000000000000
- spsr_abt :0x0000000000000000
- spsr_und :0x0000000000000000
- spsr_irq :0x0000000000000000
- spsr_fiq :0x0000000000000000
- sctlr_el1 :0x0000000030C81807
- actlr_el1 :0x0000000000000000
- cpacr_el1 :0x0000000000300000
- csselr_el1 :0x0000000000000002
- sp_el1 :0x0000000004028800
- esr_el1 :0x0000000000000000
- ttbr0_el1 :0x000000000402C200
- ttbr1_el1 :0x0000000000000000
- mair_el1 :0x00000000000004FF
- amair_el1 :0x0000000000000000
- tcr_el1 :0x0000000000003520
- tpidr_el1 :0x0000000000000000
- tpidr_el0 :0x0000000000000000
- tpidrro_el0 :0x0000000000000000
- dacr32_el2 :0x0000000000000000
- ifsr32_el2 :0x0000000000000000
- par_el1 :0x0000000000000000
- far_el1 :0x0000000000000000
- afsr0_el1 :0x0000000000000000
- afsr1_el1 :0x0000000000000000
- contextidr_el1 :0x0000000000000000
- vbar_el1 :0x0000000004027000
- cntp_ctl_el0 :0x0000000000000000
- cntp_cval_el0 :0x0000000000000000
- cntv_ctl_el0 :0x0000000000000000
- cntv_cval_el0 :0x0000000000000000
- cntkctl_el1 :0x0000000000000000
- sp_el0 :0x0000000004010780
-
-Guidelines for Reset Handlers
------------------------------
-
-TF-A implements a framework that allows CPU and platform ports to perform
-actions very early after a CPU is released from reset in both the cold and warm
-boot paths. This is done by calling the ``reset_handler()`` function in both
-the BL1 and BL31 images. It in turn calls the platform and CPU specific reset
-handling functions.
-
-Details for implementing a CPU specific reset handler can be found in
-Section 8. Details for implementing a platform specific reset handler can be
-found in the `Porting Guide`_ (see the ``plat_reset_handler()`` function).
-
-When adding functionality to a reset handler, keep in mind that if a different
-reset handling behavior is required between the first and the subsequent
-invocations of the reset handling code, this should be detected at runtime.
-In other words, the reset handler should be able to detect whether an action has
-already been performed and act as appropriate. Possible courses of actions are,
-e.g. skip the action the second time, or undo/redo it.
-
-Configuring secure interrupts
------------------------------
-
-The GIC driver is responsible for performing initial configuration of secure
-interrupts on the platform. To this end, the platform is expected to provide the
-GIC driver (either GICv2 or GICv3, as selected by the platform) with the
-interrupt configuration during the driver initialisation.
-
-Secure interrupt configuration are specified in an array of secure interrupt
-properties. In this scheme, in both GICv2 and GICv3 driver data structures, the
-``interrupt_props`` member points to an array of interrupt properties. Each
-element of the array specifies the interrupt number and its attributes
-(priority, group, configuration). Each element of the array shall be populated
-by the macro ``INTR_PROP_DESC()``. The macro takes the following arguments:
-
-- 10-bit interrupt number,
-
-- 8-bit interrupt priority,
-
-- Interrupt type (one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1``,
- ``INTR_TYPE_NS``),
-
-- Interrupt configuration (either ``GIC_INTR_CFG_LEVEL`` or
- ``GIC_INTR_CFG_EDGE``).
-
-CPU specific operations framework
----------------------------------
-
-Certain aspects of the Armv8-A architecture are implementation defined,
-that is, certain behaviours are not architecturally defined, but must be
-defined and documented by individual processor implementations. TF-A
-implements a framework which categorises the common implementation defined
-behaviours and allows a processor to export its implementation of that
-behaviour. The categories are:
-
-#. Processor specific reset sequence.
-
-#. Processor specific power down sequences.
-
-#. Processor specific register dumping as a part of crash reporting.
-
-#. Errata status reporting.
-
-Each of the above categories fulfils a different requirement.
-
-#. allows any processor specific initialization before the caches and MMU
- are turned on, like implementation of errata workarounds, entry into
- the intra-cluster coherency domain etc.
-
-#. allows each processor to implement the power down sequence mandated in
- its Technical Reference Manual (TRM).
-
-#. allows a processor to provide additional information to the developer
- in the event of a crash, for example Cortex-A53 has registers which
- can expose the data cache contents.
-
-#. allows a processor to define a function that inspects and reports the status
- of all errata workarounds on that processor.
-
-Please note that only 2. is mandated by the TRM.
-
-The CPU specific operations framework scales to accommodate a large number of
-different CPUs during power down and reset handling. The platform can specify
-any CPU optimization it wants to enable for each CPU. It can also specify
-the CPU errata workarounds to be applied for each CPU type during reset
-handling by defining CPU errata compile time macros. Details on these macros
-can be found in the `cpu-specific-build-macros.rst`_ file.
-
-The CPU specific operations framework depends on the ``cpu_ops`` structure which
-needs to be exported for each type of CPU in the platform. It is defined in
-``include/lib/cpus/aarch64/cpu_macros.S`` and has the following fields : ``midr``,
-``reset_func()``, ``cpu_pwr_down_ops`` (array of power down functions) and
-``cpu_reg_dump()``.
-
-The CPU specific files in ``lib/cpus`` export a ``cpu_ops`` data structure with
-suitable handlers for that CPU. For example, ``lib/cpus/aarch64/cortex_a53.S``
-exports the ``cpu_ops`` for Cortex-A53 CPU. According to the platform
-configuration, these CPU specific files must be included in the build by
-the platform makefile. The generic CPU specific operations framework code exists
-in ``lib/cpus/aarch64/cpu_helpers.S``.
-
-CPU specific Reset Handling
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-After a reset, the state of the CPU when it calls generic reset handler is:
-MMU turned off, both instruction and data caches turned off and not part
-of any coherency domain.
-
-The BL entrypoint code first invokes the ``plat_reset_handler()`` to allow
-the platform to perform any system initialization required and any system
-errata workarounds that needs to be applied. The ``get_cpu_ops_ptr()`` reads
-the current CPU midr, finds the matching ``cpu_ops`` entry in the ``cpu_ops``
-array and returns it. Note that only the part number and implementer fields
-in midr are used to find the matching ``cpu_ops`` entry. The ``reset_func()`` in
-the returned ``cpu_ops`` is then invoked which executes the required reset
-handling for that CPU and also any errata workarounds enabled by the platform.
-This function must preserve the values of general purpose registers x20 to x29.
-
-Refer to Section "Guidelines for Reset Handlers" for general guidelines
-regarding placement of code in a reset handler.
-
-CPU specific power down sequence
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-During the BL31 initialization sequence, the pointer to the matching ``cpu_ops``
-entry is stored in per-CPU data by ``init_cpu_ops()`` so that it can be quickly
-retrieved during power down sequences.
-
-Various CPU drivers register handlers to perform power down at certain power
-levels for that specific CPU. The PSCI service, upon receiving a power down
-request, determines the highest power level at which to execute power down
-sequence for a particular CPU. It uses the ``prepare_cpu_pwr_dwn()`` function to
-pick the right power down handler for the requested level. The function
-retrieves ``cpu_ops`` pointer member of per-CPU data, and from that, further
-retrieves ``cpu_pwr_down_ops`` array, and indexes into the required level. If the
-requested power level is higher than what a CPU driver supports, the handler
-registered for highest level is invoked.
-
-At runtime the platform hooks for power down are invoked by the PSCI service to
-perform platform specific operations during a power down sequence, for example
-turning off CCI coherency during a cluster power down.
-
-CPU specific register reporting during crash
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If the crash reporting is enabled in BL31, when a crash occurs, the crash
-reporting framework calls ``do_cpu_reg_dump`` which retrieves the matching
-``cpu_ops`` using ``get_cpu_ops_ptr()`` function. The ``cpu_reg_dump()`` in
-``cpu_ops`` is invoked, which then returns the CPU specific register values to
-be reported and a pointer to the ASCII list of register names in a format
-expected by the crash reporting framework.
-
-CPU errata status reporting
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Errata workarounds for CPUs supported in TF-A are applied during both cold and
-warm boots, shortly after reset. Individual Errata workarounds are enabled as
-build options. Some errata workarounds have potential run-time implications;
-therefore some are enabled by default, others not. Platform ports shall
-override build options to enable or disable errata as appropriate. The CPU
-drivers take care of applying errata workarounds that are enabled and applicable
-to a given CPU. Refer to the section titled *CPU Errata Workarounds* in `CPUBM`_
-for more information.
-
-Functions in CPU drivers that apply errata workaround must follow the
-conventions listed below.
-
-The errata workaround must be authored as two separate functions:
-
-- One that checks for errata. This function must determine whether that errata
- applies to the current CPU. Typically this involves matching the current
- CPUs revision and variant against a value that's known to be affected by the
- errata. If the function determines that the errata applies to this CPU, it
- must return ``ERRATA_APPLIES``; otherwise, it must return
- ``ERRATA_NOT_APPLIES``. The utility functions ``cpu_get_rev_var`` and
- ``cpu_rev_var_ls`` functions may come in handy for this purpose.
-
-For an errata identified as ``E``, the check function must be named
-``check_errata_E``.
-
-This function will be invoked at different times, both from assembly and from
-C run time. Therefore it must follow AAPCS, and must not use stack.
-
-- Another one that applies the errata workaround. This function would call the
- check function described above, and applies errata workaround if required.
-
-CPU drivers that apply errata workaround can optionally implement an assembly
-function that report the status of errata workarounds pertaining to that CPU.
-For a driver that registers the CPU, for example, ``cpux`` via ``declare_cpu_ops``
-macro, the errata reporting function, if it exists, must be named
-``cpux_errata_report``. This function will always be called with MMU enabled; it
-must follow AAPCS and may use stack.
-
-In a debug build of TF-A, on a CPU that comes out of reset, both BL1 and the
-runtime firmware (BL31 in AArch64, and BL32 in AArch32) will invoke errata
-status reporting function, if one exists, for that type of CPU.
-
-To report the status of each errata workaround, the function shall use the
-assembler macro ``report_errata``, passing it:
-
-- The build option that enables the errata;
-
-- The name of the CPU: this must be the same identifier that CPU driver
- registered itself with, using ``declare_cpu_ops``;
-
-- And the errata identifier: the identifier must match what's used in the
- errata's check function described above.
-
-The errata status reporting function will be called once per CPU type/errata
-combination during the software's active life time.
-
-It's expected that whenever an errata workaround is submitted to TF-A, the
-errata reporting function is appropriately extended to report its status as
-well.
-
-Reporting the status of errata workaround is for informational purpose only; it
-has no functional significance.
-
-Memory layout of BL images
---------------------------
-
-Each bootloader image can be divided in 2 parts:
-
-- the static contents of the image. These are data actually stored in the
- binary on the disk. In the ELF terminology, they are called ``PROGBITS``
- sections;
-
-- the run-time contents of the image. These are data that don't occupy any
- space in the binary on the disk. The ELF binary just contains some
- metadata indicating where these data will be stored at run-time and the
- corresponding sections need to be allocated and initialized at run-time.
- In the ELF terminology, they are called ``NOBITS`` sections.
-
-All PROGBITS sections are grouped together at the beginning of the image,
-followed by all NOBITS sections. This is true for all TF-A images and it is
-governed by the linker scripts. This ensures that the raw binary images are
-as small as possible. If a NOBITS section was inserted in between PROGBITS
-sections then the resulting binary file would contain zero bytes in place of
-this NOBITS section, making the image unnecessarily bigger. Smaller images
-allow faster loading from the FIP to the main memory.
-
-Linker scripts and symbols
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Each bootloader stage image layout is described by its own linker script. The
-linker scripts export some symbols into the program symbol table. Their values
-correspond to particular addresses. TF-A code can refer to these symbols to
-figure out the image memory layout.
-
-Linker symbols follow the following naming convention in TF-A.
-
-- ``__<SECTION>_START__``
-
- Start address of a given section named ``<SECTION>``.
-
-- ``__<SECTION>_END__``
-
- End address of a given section named ``<SECTION>``. If there is an alignment
- constraint on the section's end address then ``__<SECTION>_END__`` corresponds
- to the end address of the section's actual contents, rounded up to the right
- boundary. Refer to the value of ``__<SECTION>_UNALIGNED_END__`` to know the
- actual end address of the section's contents.
-
-- ``__<SECTION>_UNALIGNED_END__``
-
- End address of a given section named ``<SECTION>`` without any padding or
- rounding up due to some alignment constraint.
-
-- ``__<SECTION>_SIZE__``
-
- Size (in bytes) of a given section named ``<SECTION>``. If there is an
- alignment constraint on the section's end address then ``__<SECTION>_SIZE__``
- corresponds to the size of the section's actual contents, rounded up to the
- right boundary. In other words, ``__<SECTION>_SIZE__ = __<SECTION>_END__ - _<SECTION>_START__``. Refer to the value of ``__<SECTION>_UNALIGNED_SIZE__``
- to know the actual size of the section's contents.
-
-- ``__<SECTION>_UNALIGNED_SIZE__``
-
- Size (in bytes) of a given section named ``<SECTION>`` without any padding or
- rounding up due to some alignment constraint. In other words,
- ``__<SECTION>_UNALIGNED_SIZE__ = __<SECTION>_UNALIGNED_END__ - __<SECTION>_START__``.
-
-Some of the linker symbols are mandatory as TF-A code relies on them to be
-defined. They are listed in the following subsections. Some of them must be
-provided for each bootloader stage and some are specific to a given bootloader
-stage.
-
-The linker scripts define some extra, optional symbols. They are not actually
-used by any code but they help in understanding the bootloader images' memory
-layout as they are easy to spot in the link map files.
-
-Common linker symbols
-^^^^^^^^^^^^^^^^^^^^^
-
-All BL images share the following requirements:
-
-- The BSS section must be zero-initialised before executing any C code.
-- The coherent memory section (if enabled) must be zero-initialised as well.
-- The MMU setup code needs to know the extents of the coherent and read-only
- memory regions to set the right memory attributes. When
- ``SEPARATE_CODE_AND_RODATA=1``, it needs to know more specifically how the
- read-only memory region is divided between code and data.
-
-The following linker symbols are defined for this purpose:
-
-- ``__BSS_START__``
-- ``__BSS_SIZE__``
-- ``__COHERENT_RAM_START__`` Must be aligned on a page-size boundary.
-- ``__COHERENT_RAM_END__`` Must be aligned on a page-size boundary.
-- ``__COHERENT_RAM_UNALIGNED_SIZE__``
-- ``__RO_START__``
-- ``__RO_END__``
-- ``__TEXT_START__``
-- ``__TEXT_END__``
-- ``__RODATA_START__``
-- ``__RODATA_END__``
-
-BL1's linker symbols
-^^^^^^^^^^^^^^^^^^^^
-
-BL1 being the ROM image, it has additional requirements. BL1 resides in ROM and
-it is entirely executed in place but it needs some read-write memory for its
-mutable data. Its ``.data`` section (i.e. its allocated read-write data) must be
-relocated from ROM to RAM before executing any C code.
-
-The following additional linker symbols are defined for BL1:
-
-- ``__BL1_ROM_END__`` End address of BL1's ROM contents, covering its code
- and ``.data`` section in ROM.
-- ``__DATA_ROM_START__`` Start address of the ``.data`` section in ROM. Must be
- aligned on a 16-byte boundary.
-- ``__DATA_RAM_START__`` Address in RAM where the ``.data`` section should be
- copied over. Must be aligned on a 16-byte boundary.
-- ``__DATA_SIZE__`` Size of the ``.data`` section (in ROM or RAM).
-- ``__BL1_RAM_START__`` Start address of BL1 read-write data.
-- ``__BL1_RAM_END__`` End address of BL1 read-write data.
-
-How to choose the right base addresses for each bootloader stage image
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-There is currently no support for dynamic image loading in TF-A. This means
-that all bootloader images need to be linked against their ultimate runtime
-locations and the base addresses of each image must be chosen carefully such
-that images don't overlap each other in an undesired way. As the code grows,
-the base addresses might need adjustments to cope with the new memory layout.
-
-The memory layout is completely specific to the platform and so there is no
-general recipe for choosing the right base addresses for each bootloader image.
-However, there are tools to aid in understanding the memory layout. These are
-the link map files: ``build/<platform>/<build-type>/bl<x>/bl<x>.map``, with ``<x>``
-being the stage bootloader. They provide a detailed view of the memory usage of
-each image. Among other useful information, they provide the end address of
-each image.
-
-- ``bl1.map`` link map file provides ``__BL1_RAM_END__`` address.
-- ``bl2.map`` link map file provides ``__BL2_END__`` address.
-- ``bl31.map`` link map file provides ``__BL31_END__`` address.
-- ``bl32.map`` link map file provides ``__BL32_END__`` address.
-
-For each bootloader image, the platform code must provide its start address
-as well as a limit address that it must not overstep. The latter is used in the
-linker scripts to check that the image doesn't grow past that address. If that
-happens, the linker will issue a message similar to the following:
-
-::
-
- aarch64-none-elf-ld: BLx has exceeded its limit.
-
-Additionally, if the platform memory layout implies some image overlaying like
-on FVP, BL31 and TSP need to know the limit address that their PROGBITS
-sections must not overstep. The platform code must provide those.
-
-TF-A does not provide any mechanism to verify at boot time that the memory
-to load a new image is free to prevent overwriting a previously loaded image.
-The platform must specify the memory available in the system for all the
-relevant BL images to be loaded.
-
-For example, in the case of BL1 loading BL2, ``bl1_plat_sec_mem_layout()`` will
-return the region defined by the platform where BL1 intends to load BL2. The
-``load_image()`` function performs bounds check for the image size based on the
-base and maximum image size provided by the platforms. Platforms must take
-this behaviour into account when defining the base/size for each of the images.
-
-Memory layout on Arm development platforms
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The following list describes the memory layout on the Arm development platforms:
-
-- A 4KB page of shared memory is used for communication between Trusted
- Firmware and the platform's power controller. This is located at the base of
- Trusted SRAM. The amount of Trusted SRAM available to load the bootloader
- images is reduced by the size of the shared memory.
-
- The shared memory is used to store the CPUs' entrypoint mailbox. On Juno,
- this is also used for the MHU payload when passing messages to and from the
- SCP.
-
-- Another 4 KB page is reserved for passing memory layout between BL1 and BL2
- and also the dynamic firmware configurations.
-
-- On FVP, BL1 is originally sitting in the Trusted ROM at address ``0x0``. On
- Juno, BL1 resides in flash memory at address ``0x0BEC0000``. BL1 read-write
- data are relocated to the top of Trusted SRAM at runtime.
-
-- BL2 is loaded below BL1 RW
-
-- EL3 Runtime Software, BL31 for AArch64 and BL32 for AArch32 (e.g. SP_MIN),
- is loaded at the top of the Trusted SRAM, such that its NOBITS sections will
- overwrite BL1 R/W data and BL2. This implies that BL1 global variables
- remain valid only until execution reaches the EL3 Runtime Software entry
- point during a cold boot.
-
-- On Juno, SCP_BL2 is loaded temporarily into the EL3 Runtime Software memory
- region and transfered to the SCP before being overwritten by EL3 Runtime
- Software.
-
-- BL32 (for AArch64) can be loaded in one of the following locations:
-
- - Trusted SRAM
- - Trusted DRAM (FVP only)
- - Secure region of DRAM (top 16MB of DRAM configured by the TrustZone
- controller)
-
- When BL32 (for AArch64) is loaded into Trusted SRAM, it is loaded below
- BL31.
-
-The location of the BL32 image will result in different memory maps. This is
-illustrated for both FVP and Juno in the following diagrams, using the TSP as
-an example.
-
-Note: Loading the BL32 image in TZC secured DRAM doesn't change the memory
-layout of the other images in Trusted SRAM.
-
-CONFIG section in memory layouts shown below contains:
-
-::
-
- +--------------------+
- |bl2_mem_params_descs|
- |--------------------|
- | fw_configs |
- +--------------------+
-
-``bl2_mem_params_descs`` contains parameters passed from BL2 to next the
-BL image during boot.
-
-``fw_configs`` includes soc_fw_config, tos_fw_config and tb_fw_config.
-
-**FVP with TSP in Trusted SRAM with firmware configs :**
-(These diagrams only cover the AArch64 case)
-
-::
-
- DRAM
- 0xffffffff +----------+
- : :
- |----------|
- |HW_CONFIG |
- 0x83000000 |----------| (non-secure)
- | |
- 0x80000000 +----------+
-
- Trusted SRAM
- 0x04040000 +----------+ loaded by BL2 +----------------+
- | BL1 (rw) | <<<<<<<<<<<<< | |
- |----------| <<<<<<<<<<<<< | BL31 NOBITS |
- | BL2 | <<<<<<<<<<<<< | |
- |----------| <<<<<<<<<<<<< |----------------|
- | | <<<<<<<<<<<<< | BL31 PROGBITS |
- | | <<<<<<<<<<<<< |----------------|
- | | <<<<<<<<<<<<< | BL32 |
- 0x04002000 +----------+ +----------------+
- | CONFIG |
- 0x04001000 +----------+
- | Shared |
- 0x04000000 +----------+
-
- Trusted ROM
- 0x04000000 +----------+
- | BL1 (ro) |
- 0x00000000 +----------+
-
-**FVP with TSP in Trusted DRAM with firmware configs (default option):**
-
-::
-
- DRAM
- 0xffffffff +--------------+
- : :
- |--------------|
- | HW_CONFIG |
- 0x83000000 |--------------| (non-secure)
- | |
- 0x80000000 +--------------+
-
- Trusted DRAM
- 0x08000000 +--------------+
- | BL32 |
- 0x06000000 +--------------+
-
- Trusted SRAM
- 0x04040000 +--------------+ loaded by BL2 +----------------+
- | BL1 (rw) | <<<<<<<<<<<<< | |
- |--------------| <<<<<<<<<<<<< | BL31 NOBITS |
- | BL2 | <<<<<<<<<<<<< | |
- |--------------| <<<<<<<<<<<<< |----------------|
- | | <<<<<<<<<<<<< | BL31 PROGBITS |
- | | +----------------+
- +--------------+
- | CONFIG |
- 0x04001000 +--------------+
- | Shared |
- 0x04000000 +--------------+
-
- Trusted ROM
- 0x04000000 +--------------+
- | BL1 (ro) |
- 0x00000000 +--------------+
-
-**FVP with TSP in TZC-Secured DRAM with firmware configs :**
-
-::
-
- DRAM
- 0xffffffff +----------+
- | BL32 | (secure)
- 0xff000000 +----------+
- | |
- |----------|
- |HW_CONFIG |
- 0x83000000 |----------| (non-secure)
- | |
- 0x80000000 +----------+
-
- Trusted SRAM
- 0x04040000 +----------+ loaded by BL2 +----------------+
- | BL1 (rw) | <<<<<<<<<<<<< | |
- |----------| <<<<<<<<<<<<< | BL31 NOBITS |
- | BL2 | <<<<<<<<<<<<< | |
- |----------| <<<<<<<<<<<<< |----------------|
- | | <<<<<<<<<<<<< | BL31 PROGBITS |
- | | +----------------+
- 0x04002000 +----------+
- | CONFIG |
- 0x04001000 +----------+
- | Shared |
- 0x04000000 +----------+
-
- Trusted ROM
- 0x04000000 +----------+
- | BL1 (ro) |
- 0x00000000 +----------+
-
-**Juno with BL32 in Trusted SRAM :**
-
-::
-
- Flash0
- 0x0C000000 +----------+
- : :
- 0x0BED0000 |----------|
- | BL1 (ro) |
- 0x0BEC0000 |----------|
- : :
- 0x08000000 +----------+ BL31 is loaded
- after SCP_BL2 has
- Trusted SRAM been sent to SCP
- 0x04040000 +----------+ loaded by BL2 +----------------+
- | BL1 (rw) | <<<<<<<<<<<<< | |
- |----------| <<<<<<<<<<<<< | BL31 NOBITS |
- | BL2 | <<<<<<<<<<<<< | |
- |----------| <<<<<<<<<<<<< |----------------|
- | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS |
- |----------| <<<<<<<<<<<<< |----------------|
- | | <<<<<<<<<<<<< | BL32 |
- | | +----------------+
- | |
- 0x04001000 +----------+
- | MHU |
- 0x04000000 +----------+
-
-**Juno with BL32 in TZC-secured DRAM :**
-
-::
-
- DRAM
- 0xFFE00000 +----------+
- | BL32 | (secure)
- 0xFF000000 |----------|
- | |
- : : (non-secure)
- | |
- 0x80000000 +----------+
-
- Flash0
- 0x0C000000 +----------+
- : :
- 0x0BED0000 |----------|
- | BL1 (ro) |
- 0x0BEC0000 |----------|
- : :
- 0x08000000 +----------+ BL31 is loaded
- after SCP_BL2 has
- Trusted SRAM been sent to SCP
- 0x04040000 +----------+ loaded by BL2 +----------------+
- | BL1 (rw) | <<<<<<<<<<<<< | |
- |----------| <<<<<<<<<<<<< | BL31 NOBITS |
- | BL2 | <<<<<<<<<<<<< | |
- |----------| <<<<<<<<<<<<< |----------------|
- | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS |
- |----------| +----------------+
- 0x04001000 +----------+
- | MHU |
- 0x04000000 +----------+
-
-Library at ROM
----------------
-
-Please refer to the `ROMLIB Design`_ document.
-
-Firmware Image Package (FIP)
-----------------------------
-
-Using a Firmware Image Package (FIP) allows for packing bootloader images (and
-potentially other payloads) into a single archive that can be loaded by TF-A
-from non-volatile platform storage. A driver to load images from a FIP has
-been added to the storage layer and allows a package to be read from supported
-platform storage. A tool to create Firmware Image Packages is also provided
-and described below.
-
-Firmware Image Package layout
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The FIP layout consists of a table of contents (ToC) followed by payload data.
-The ToC itself has a header followed by one or more table entries. The ToC is
-terminated by an end marker entry, and since the size of the ToC is 0 bytes,
-the offset equals the total size of the FIP file. All ToC entries describe some
-payload data that has been appended to the end of the binary package. With the
-information provided in the ToC entry the corresponding payload data can be
-retrieved.
-
-::
-
- ------------------
- | ToC Header |
- |----------------|
- | ToC Entry 0 |
- |----------------|
- | ToC Entry 1 |
- |----------------|
- | ToC End Marker |
- |----------------|
- | |
- | Data 0 |
- | |
- |----------------|
- | |
- | Data 1 |
- | |
- ------------------
-
-The ToC header and entry formats are described in the header file
-``include/tools_share/firmware_image_package.h``. This file is used by both the
-tool and TF-A.
-
-The ToC header has the following fields:
-
-::
-
- `name`: The name of the ToC. This is currently used to validate the header.
- `serial_number`: A non-zero number provided by the creation tool
- `flags`: Flags associated with this data.
- Bits 0-31: Reserved
- Bits 32-47: Platform defined
- Bits 48-63: Reserved
-
-A ToC entry has the following fields:
-
-::
-
- `uuid`: All files are referred to by a pre-defined Universally Unique
- IDentifier [UUID] . The UUIDs are defined in
- `include/tools_share/firmware_image_package.h`. The platform translates
- the requested image name into the corresponding UUID when accessing the
- package.
- `offset_address`: The offset address at which the corresponding payload data
- can be found. The offset is calculated from the ToC base address.
- `size`: The size of the corresponding payload data in bytes.
- `flags`: Flags associated with this entry. None are yet defined.
-
-Firmware Image Package creation tool
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The FIP creation tool can be used to pack specified images into a binary
-package that can be loaded by TF-A from platform storage. The tool currently
-only supports packing bootloader images. Additional image definitions can be
-added to the tool as required.
-
-The tool can be found in ``tools/fiptool``.
-
-Loading from a Firmware Image Package (FIP)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Firmware Image Package (FIP) driver can load images from a binary package on
-non-volatile platform storage. For the Arm development platforms, this is
-currently NOR FLASH.
-
-Bootloader images are loaded according to the platform policy as specified by
-the function ``plat_get_image_source()``. For the Arm development platforms, this
-means the platform will attempt to load images from a Firmware Image Package
-located at the start of NOR FLASH0.
-
-The Arm development platforms' policy is to only allow loading of a known set of
-images. The platform policy can be modified to allow additional images.
-
-Use of coherent memory in TF-A
-------------------------------
-
-There might be loss of coherency when physical memory with mismatched
-shareability, cacheability and memory attributes is accessed by multiple CPUs
-(refer to section B2.9 of `Arm ARM`_ for more details). This possibility occurs
-in TF-A during power up/down sequences when coherency, MMU and caches are
-turned on/off incrementally.
-
-TF-A defines coherent memory as a region of memory with Device nGnRE attributes
-in the translation tables. The translation granule size in TF-A is 4KB. This
-is the smallest possible size of the coherent memory region.
-
-By default, all data structures which are susceptible to accesses with
-mismatched attributes from various CPUs are allocated in a coherent memory
-region (refer to section 2.1 of `Porting Guide`_). The coherent memory region
-accesses are Outer Shareable, non-cacheable and they can be accessed
-with the Device nGnRE attributes when the MMU is turned on. Hence, at the
-expense of at least an extra page of memory, TF-A is able to work around
-coherency issues due to mismatched memory attributes.
-
-The alternative to the above approach is to allocate the susceptible data
-structures in Normal WriteBack WriteAllocate Inner shareable memory. This
-approach requires the data structures to be designed so that it is possible to
-work around the issue of mismatched memory attributes by performing software
-cache maintenance on them.
-
-Disabling the use of coherent memory in TF-A
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It might be desirable to avoid the cost of allocating coherent memory on
-platforms which are memory constrained. TF-A enables inclusion of coherent
-memory in firmware images through the build flag ``USE_COHERENT_MEM``.
-This flag is enabled by default. It can be disabled to choose the second
-approach described above.
-
-The below sections analyze the data structures allocated in the coherent memory
-region and the changes required to allocate them in normal memory.
-
-Coherent memory usage in PSCI implementation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``psci_non_cpu_pd_nodes`` data structure stores the platform's power domain
-tree information for state management of power domains. By default, this data
-structure is allocated in the coherent memory region in TF-A because it can be
-accessed by multiple CPUs, either with caches enabled or disabled.
-
-.. code:: c
-
- typedef struct non_cpu_pwr_domain_node {
- /*
- * Index of the first CPU power domain node level 0 which has this node
- * as its parent.
- */
- unsigned int cpu_start_idx;
-
- /*
- * Number of CPU power domains which are siblings of the domain indexed
- * by 'cpu_start_idx' i.e. all the domains in the range 'cpu_start_idx
- * -> cpu_start_idx + ncpus' have this node as their parent.
- */
- unsigned int ncpus;
-
- /*
- * Index of the parent power domain node.
- */
- unsigned int parent_node;
-
- plat_local_state_t local_state;
-
- unsigned char level;
-
- /* For indexing the psci_lock array*/
- unsigned char lock_index;
- } non_cpu_pd_node_t;
-
-In order to move this data structure to normal memory, the use of each of its
-fields must be analyzed. Fields like ``cpu_start_idx``, ``ncpus``, ``parent_node``
-``level`` and ``lock_index`` are only written once during cold boot. Hence removing
-them from coherent memory involves only doing a clean and invalidate of the
-cache lines after these fields are written.
-
-The field ``local_state`` can be concurrently accessed by multiple CPUs in
-different cache states. A Lamport's Bakery lock ``psci_locks`` is used to ensure
-mutual exclusion to this field and a clean and invalidate is needed after it
-is written.
-
-Bakery lock data
-~~~~~~~~~~~~~~~~
-
-The bakery lock data structure ``bakery_lock_t`` is allocated in coherent memory
-and is accessed by multiple CPUs with mismatched attributes. ``bakery_lock_t`` is
-defined as follows:
-
-.. code:: c
-
- typedef struct bakery_lock {
- /*
- * The lock_data is a bit-field of 2 members:
- * Bit[0] : choosing. This field is set when the CPU is
- * choosing its bakery number.
- * Bits[1 - 15] : number. This is the bakery number allocated.
- */
- volatile uint16_t lock_data[BAKERY_LOCK_MAX_CPUS];
- } bakery_lock_t;
-
-It is a characteristic of Lamport's Bakery algorithm that the volatile per-CPU
-fields can be read by all CPUs but only written to by the owning CPU.
-
-Depending upon the data cache line size, the per-CPU fields of the
-``bakery_lock_t`` structure for multiple CPUs may exist on a single cache line.
-These per-CPU fields can be read and written during lock contention by multiple
-CPUs with mismatched memory attributes. Since these fields are a part of the
-lock implementation, they do not have access to any other locking primitive to
-safeguard against the resulting coherency issues. As a result, simple software
-cache maintenance is not enough to allocate them in coherent memory. Consider
-the following example.
-
-CPU0 updates its per-CPU field with data cache enabled. This write updates a
-local cache line which contains a copy of the fields for other CPUs as well. Now
-CPU1 updates its per-CPU field of the ``bakery_lock_t`` structure with data cache
-disabled. CPU1 then issues a DCIVAC operation to invalidate any stale copies of
-its field in any other cache line in the system. This operation will invalidate
-the update made by CPU0 as well.
-
-To use bakery locks when ``USE_COHERENT_MEM`` is disabled, the lock data structure
-has been redesigned. The changes utilise the characteristic of Lamport's Bakery
-algorithm mentioned earlier. The bakery_lock structure only allocates the memory
-for a single CPU. The macro ``DEFINE_BAKERY_LOCK`` allocates all the bakery locks
-needed for a CPU into a section ``bakery_lock``. The linker allocates the memory
-for other cores by using the total size allocated for the bakery_lock section
-and multiplying it with (PLATFORM_CORE_COUNT - 1). This enables software to
-perform software cache maintenance on the lock data structure without running
-into coherency issues associated with mismatched attributes.
-
-The bakery lock data structure ``bakery_info_t`` is defined for use when
-``USE_COHERENT_MEM`` is disabled as follows:
-
-.. code:: c
-
- typedef struct bakery_info {
- /*
- * The lock_data is a bit-field of 2 members:
- * Bit[0] : choosing. This field is set when the CPU is
- * choosing its bakery number.
- * Bits[1 - 15] : number. This is the bakery number allocated.
- */
- volatile uint16_t lock_data;
- } bakery_info_t;
-
-The ``bakery_info_t`` represents a single per-CPU field of one lock and
-the combination of corresponding ``bakery_info_t`` structures for all CPUs in the
-system represents the complete bakery lock. The view in memory for a system
-with n bakery locks are:
-
-::
-
- bakery_lock section start
- |----------------|
- | `bakery_info_t`| <-- Lock_0 per-CPU field
- | Lock_0 | for CPU0
- |----------------|
- | `bakery_info_t`| <-- Lock_1 per-CPU field
- | Lock_1 | for CPU0
- |----------------|
- | .... |
- |----------------|
- | `bakery_info_t`| <-- Lock_N per-CPU field
- | Lock_N | for CPU0
- ------------------
- | XXXXX |
- | Padding to |
- | next Cache WB | <--- Calculate PERCPU_BAKERY_LOCK_SIZE, allocate
- | Granule | continuous memory for remaining CPUs.
- ------------------
- | `bakery_info_t`| <-- Lock_0 per-CPU field
- | Lock_0 | for CPU1
- |----------------|
- | `bakery_info_t`| <-- Lock_1 per-CPU field
- | Lock_1 | for CPU1
- |----------------|
- | .... |
- |----------------|
- | `bakery_info_t`| <-- Lock_N per-CPU field
- | Lock_N | for CPU1
- ------------------
- | XXXXX |
- | Padding to |
- | next Cache WB |
- | Granule |
- ------------------
-
-Consider a system of 2 CPUs with 'N' bakery locks as shown above. For an
-operation on Lock_N, the corresponding ``bakery_info_t`` in both CPU0 and CPU1
-``bakery_lock`` section need to be fetched and appropriate cache operations need
-to be performed for each access.
-
-On Arm Platforms, bakery locks are used in psci (``psci_locks``) and power controller
-driver (``arm_lock``).
-
-Non Functional Impact of removing coherent memory
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Removal of the coherent memory region leads to the additional software overhead
-of performing cache maintenance for the affected data structures. However, since
-the memory where the data structures are allocated is cacheable, the overhead is
-mostly mitigated by an increase in performance.
-
-There is however a performance impact for bakery locks, due to:
-
-- Additional cache maintenance operations, and
-- Multiple cache line reads for each lock operation, since the bakery locks
- for each CPU are distributed across different cache lines.
-
-The implementation has been optimized to minimize this additional overhead.
-Measurements indicate that when bakery locks are allocated in Normal memory, the
-minimum latency of acquiring a lock is on an average 3-4 micro seconds whereas
-in Device memory the same is 2 micro seconds. The measurements were done on the
-Juno Arm development platform.
-
-As mentioned earlier, almost a page of memory can be saved by disabling
-``USE_COHERENT_MEM``. Each platform needs to consider these trade-offs to decide
-whether coherent memory should be used. If a platform disables
-``USE_COHERENT_MEM`` and needs to use bakery locks in the porting layer, it can
-optionally define macro ``PLAT_PERCPU_BAKERY_LOCK_SIZE`` (see the
-`Porting Guide`_). Refer to the reference platform code for examples.
-
-Isolating code and read-only data on separate memory pages
-----------------------------------------------------------
-
-In the Armv8-A VMSA, translation table entries include fields that define the
-properties of the target memory region, such as its access permissions. The
-smallest unit of memory that can be addressed by a translation table entry is
-a memory page. Therefore, if software needs to set different permissions on two
-memory regions then it needs to map them using different memory pages.
-
-The default memory layout for each BL image is as follows:
-
-::
-
- | ... |
- +-------------------+
- | Read-write data |
- +-------------------+ Page boundary
- | <Padding> |
- +-------------------+
- | Exception vectors |
- +-------------------+ 2 KB boundary
- | <Padding> |
- +-------------------+
- | Read-only data |
- +-------------------+
- | Code |
- +-------------------+ BLx_BASE
-
-Note: The 2KB alignment for the exception vectors is an architectural
-requirement.
-
-The read-write data start on a new memory page so that they can be mapped with
-read-write permissions, whereas the code and read-only data below are configured
-as read-only.
-
-However, the read-only data are not aligned on a page boundary. They are
-contiguous to the code. Therefore, the end of the code section and the beginning
-of the read-only data one might share a memory page. This forces both to be
-mapped with the same memory attributes. As the code needs to be executable, this
-means that the read-only data stored on the same memory page as the code are
-executable as well. This could potentially be exploited as part of a security
-attack.
-
-TF provides the build flag ``SEPARATE_CODE_AND_RODATA`` to isolate the code and
-read-only data on separate memory pages. This in turn allows independent control
-of the access permissions for the code and read-only data. In this case,
-platform code gets a finer-grained view of the image layout and can
-appropriately map the code region as executable and the read-only data as
-execute-never.
-
-This has an impact on memory footprint, as padding bytes need to be introduced
-between the code and read-only data to ensure the segregation of the two. To
-limit the memory cost, this flag also changes the memory layout such that the
-code and exception vectors are now contiguous, like so:
-
-::
-
- | ... |
- +-------------------+
- | Read-write data |
- +-------------------+ Page boundary
- | <Padding> |
- +-------------------+
- | Read-only data |
- +-------------------+ Page boundary
- | <Padding> |
- +-------------------+
- | Exception vectors |
- +-------------------+ 2 KB boundary
- | <Padding> |
- +-------------------+
- | Code |
- +-------------------+ BLx_BASE
-
-With this more condensed memory layout, the separation of read-only data will
-add zero or one page to the memory footprint of each BL image. Each platform
-should consider the trade-off between memory footprint and security.
-
-This build flag is disabled by default, minimising memory footprint. On Arm
-platforms, it is enabled.
-
-Publish and Subscribe Framework
--------------------------------
-
-The Publish and Subscribe Framework allows EL3 components to define and publish
-events, to which other EL3 components can subscribe.
-
-The following macros are provided by the framework:
-
-- ``REGISTER_PUBSUB_EVENT(event)``: Defines an event, and takes one argument,
- the event name, which must be a valid C identifier. All calls to
- ``REGISTER_PUBSUB_EVENT`` macro must be placed in the file
- ``pubsub_events.h``.
-
-- ``PUBLISH_EVENT_ARG(event, arg)``: Publishes a defined event, by iterating
- subscribed handlers and calling them in turn. The handlers will be passed the
- parameter ``arg``. The expected use-case is to broadcast an event.
-
-- ``PUBLISH_EVENT(event)``: Like ``PUBLISH_EVENT_ARG``, except that the value
- ``NULL`` is passed to subscribed handlers.
-
-- ``SUBSCRIBE_TO_EVENT(event, handler)``: Registers the ``handler`` to
- subscribe to ``event``. The handler will be executed whenever the ``event``
- is published.
-
-- ``for_each_subscriber(event, subscriber)``: Iterates through all handlers
- subscribed for ``event``. ``subscriber`` must be a local variable of type
- ``pubsub_cb_t *``, and will point to each subscribed handler in turn during
- iteration. This macro can be used for those patterns that none of the
- ``PUBLISH_EVENT_*()`` macros cover.
-
-Publishing an event that wasn't defined using ``REGISTER_PUBSUB_EVENT`` will
-result in build error. Subscribing to an undefined event however won't.
-
-Subscribed handlers must be of type ``pubsub_cb_t``, with following function
-signature:
-
-::
-
- typedef void* (*pubsub_cb_t)(const void *arg);
-
-There may be arbitrary number of handlers registered to the same event. The
-order in which subscribed handlers are notified when that event is published is
-not defined. Subscribed handlers may be executed in any order; handlers should
-not assume any relative ordering amongst them.
-
-Publishing an event on a PE will result in subscribed handlers executing on that
-PE only; it won't cause handlers to execute on a different PE.
-
-Note that publishing an event on a PE blocks until all the subscribed handlers
-finish executing on the PE.
-
-TF-A generic code publishes and subscribes to some events within. Platform
-ports are discouraged from subscribing to them. These events may be withdrawn,
-renamed, or have their semantics altered in the future. Platforms may however
-register, publish, and subscribe to platform-specific events.
-
-Publish and Subscribe Example
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A publisher that wants to publish event ``foo`` would:
-
-- Define the event ``foo`` in the ``pubsub_events.h``.
-
- ::
-
- REGISTER_PUBSUB_EVENT(foo);
-
-- Depending on the nature of event, use one of ``PUBLISH_EVENT_*()`` macros to
- publish the event at the appropriate path and time of execution.
-
-A subscriber that wants to subscribe to event ``foo`` published above would
-implement:
-
-.. code:: c
-
- void *foo_handler(const void *arg)
- {
- void *result;
-
- /* Do handling ... */
-
- return result;
- }
-
- SUBSCRIBE_TO_EVENT(foo, foo_handler);
-
-
-Reclaiming the BL31 initialization code
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A significant amount of the code used for the initialization of BL31 is never
-needed again after boot time. In order to reduce the runtime memory
-footprint, the memory used for this code can be reclaimed after initialization
-has finished and be used for runtime data.
-
-The build option ``RECLAIM_INIT_CODE`` can be set to mark this boot time code
-with a ``.text.init.*`` attribute which can be filtered and placed suitably
-within the BL image for later reclamation by the platform. The platform can
-specify the filter and the memory region for this init section in BL31 via the
-plat.ld.S linker script. For example, on the FVP, this section is placed
-overlapping the secondary CPU stacks so that after the cold boot is done, this
-memory can be reclaimed for the stacks. The init memory section is initially
-mapped with ``RO``, ``EXECUTE`` attributes. After BL31 initialization has
-completed, the FVP changes the attributes of this section to ``RW``,
-``EXECUTE_NEVER`` allowing it to be used for runtime data. The memory attributes
-are changed within the ``bl31_plat_runtime_setup`` platform hook. The init
-section section can be reclaimed for any data which is accessed after cold
-boot initialization and it is upto the platform to make the decision.
-
-Performance Measurement Framework
----------------------------------
-
-The Performance Measurement Framework (PMF) facilitates collection of
-timestamps by registered services and provides interfaces to retrieve them
-from within TF-A. A platform can choose to expose appropriate SMCs to
-retrieve these collected timestamps.
-
-By default, the global physical counter is used for the timestamp
-value and is read via ``CNTPCT_EL0``. The framework allows to retrieve
-timestamps captured by other CPUs.
-
-Timestamp identifier format
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A PMF timestamp is uniquely identified across the system via the
-timestamp ID or ``tid``. The ``tid`` is composed as follows:
-
-::
-
- Bits 0-7: The local timestamp identifier.
- Bits 8-9: Reserved.
- Bits 10-15: The service identifier.
- Bits 16-31: Reserved.
-
-#. The service identifier. Each PMF service is identified by a
- service name and a service identifier. Both the service name and
- identifier are unique within the system as a whole.
-
-#. The local timestamp identifier. This identifier is unique within a given
- service.
-
-Registering a PMF service
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To register a PMF service, the ``PMF_REGISTER_SERVICE()`` macro from ``pmf.h``
-is used. The arguments required are the service name, the service ID,
-the total number of local timestamps to be captured and a set of flags.
-
-The ``flags`` field can be specified as a bitwise-OR of the following values:
-
-::
-
- PMF_STORE_ENABLE: The timestamp is stored in memory for later retrieval.
- PMF_DUMP_ENABLE: The timestamp is dumped on the serial console.
-
-The ``PMF_REGISTER_SERVICE()`` reserves memory to store captured
-timestamps in a PMF specific linker section at build time.
-Additionally, it defines necessary functions to capture and
-retrieve a particular timestamp for the given service at runtime.
-
-The macro ``PMF_REGISTER_SERVICE()`` only enables capturing PMF timestamps
-from within TF-A. In order to retrieve timestamps from outside of TF-A, the
-``PMF_REGISTER_SERVICE_SMC()`` macro must be used instead. This macro
-accepts the same set of arguments as the ``PMF_REGISTER_SERVICE()``
-macro but additionally supports retrieving timestamps using SMCs.
-
-Capturing a timestamp
-~~~~~~~~~~~~~~~~~~~~~
-
-PMF timestamps are stored in a per-service timestamp region. On a
-system with multiple CPUs, each timestamp is captured and stored
-in a per-CPU cache line aligned memory region.
-
-Having registered the service, the ``PMF_CAPTURE_TIMESTAMP()`` macro can be
-used to capture a timestamp at the location where it is used. The macro
-takes the service name, a local timestamp identifier and a flag as arguments.
-
-The ``flags`` field argument can be zero, or ``PMF_CACHE_MAINT`` which
-instructs PMF to do cache maintenance following the capture. Cache
-maintenance is required if any of the service's timestamps are captured
-with data cache disabled.
-
-To capture a timestamp in assembly code, the caller should use
-``pmf_calc_timestamp_addr`` macro (defined in ``pmf_asm_macros.S``) to
-calculate the address of where the timestamp would be stored. The
-caller should then read ``CNTPCT_EL0`` register to obtain the timestamp
-and store it at the determined address for later retrieval.
-
-Retrieving a timestamp
-~~~~~~~~~~~~~~~~~~~~~~
-
-From within TF-A, timestamps for individual CPUs can be retrieved using either
-``PMF_GET_TIMESTAMP_BY_MPIDR()`` or ``PMF_GET_TIMESTAMP_BY_INDEX()`` macros.
-These macros accept the CPU's MPIDR value, or its ordinal position
-respectively.
-
-From outside TF-A, timestamps for individual CPUs can be retrieved by calling
-into ``pmf_smc_handler()``.
-
-.. code:: c
-
- Interface : pmf_smc_handler()
- Argument : unsigned int smc_fid, u_register_t x1,
- u_register_t x2, u_register_t x3,
- u_register_t x4, void *cookie,
- void *handle, u_register_t flags
- Return : uintptr_t
-
- smc_fid: Holds the SMC identifier which is either `PMF_SMC_GET_TIMESTAMP_32`
- when the caller of the SMC is running in AArch32 mode
- or `PMF_SMC_GET_TIMESTAMP_64` when the caller is running in AArch64 mode.
- x1: Timestamp identifier.
- x2: The `mpidr` of the CPU for which the timestamp has to be retrieved.
- This can be the `mpidr` of a different core to the one initiating
- the SMC. In that case, service specific cache maintenance may be
- required to ensure the updated copy of the timestamp is returned.
- x3: A flags value that is either 0 or `PMF_CACHE_MAINT`. If
- `PMF_CACHE_MAINT` is passed, then the PMF code will perform a
- cache invalidate before reading the timestamp. This ensures
- an updated copy is returned.
-
-The remaining arguments, ``x4``, ``cookie``, ``handle`` and ``flags`` are unused
-in this implementation.
-
-PMF code structure
-~~~~~~~~~~~~~~~~~~
-
-#. ``pmf_main.c`` consists of core functions that implement service registration,
- initialization, storing, dumping and retrieving timestamps.
-
-#. ``pmf_smc.c`` contains the SMC handling for registered PMF services.
-
-#. ``pmf.h`` contains the public interface to Performance Measurement Framework.
-
-#. ``pmf_asm_macros.S`` consists of macros to facilitate capturing timestamps in
- assembly code.
-
-#. ``pmf_helpers.h`` is an internal header used by ``pmf.h``.
-
-Armv8-A Architecture Extensions
--------------------------------
-
-TF-A makes use of Armv8-A Architecture Extensions where applicable. This
-section lists the usage of Architecture Extensions, and build flags
-controlling them.
-
-In general, and unless individually mentioned, the build options
-``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` select the Architecture Extension to
-target when building TF-A. Subsequent Arm Architecture Extensions are backward
-compatible with previous versions.
-
-The build system only requires that ``ARM_ARCH_MAJOR`` and ``ARM_ARCH_MINOR`` have a
-valid numeric value. These build options only control whether or not
-Architecture Extension-specific code is included in the build. Otherwise, TF-A
-targets the base Armv8.0-A architecture; i.e. as if ``ARM_ARCH_MAJOR`` == 8
-and ``ARM_ARCH_MINOR`` == 0, which are also their respective default values.
-
-See also the *Summary of build options* in `User Guide`_.
-
-For details on the Architecture Extension and available features, please refer
-to the respective Architecture Extension Supplement.
-
-Armv8.1-A
-~~~~~~~~~
-
-This Architecture Extension is targeted when ``ARM_ARCH_MAJOR`` >= 8, or when
-``ARM_ARCH_MAJOR`` == 8 and ``ARM_ARCH_MINOR`` >= 1.
-
-- The Compare and Swap instruction is used to implement spinlocks. Otherwise,
- the load-/store-exclusive instruction pair is used.
-
-Armv8.2-A
-~~~~~~~~~
-
-- The presence of ARMv8.2-TTCNP is detected at runtime. When it is present, the
- Common not Private (TTBRn_ELx.CnP) bit is enabled to indicate that multiple
- Processing Elements in the same Inner Shareable domain use the same
- translation table entries for a given stage of translation for a particular
- translation regime.
-
-Armv8.3-A
-~~~~~~~~~
-
-- Pointer authentication features of Armv8.3-A are unconditionally enabled in
- the Non-secure world so that lower ELs are allowed to use them without
- causing a trap to EL3.
-
- In order to enable the Secure world to use it, ``CTX_INCLUDE_PAUTH_REGS``
- must be set to 1. This will add all pointer authentication system registers
- to the context that is saved when doing a world switch.
-
- The TF-A itself has support for pointer authentication at runtime
- that can be enabled by setting both options ``ENABLE_PAUTH`` and
- ``CTX_INCLUDE_PAUTH_REGS`` to 1. This enables pointer authentication in BL1,
- BL2, BL31, and the TSP if it is used.
-
- These options are experimental features.
-
- Note that Pointer Authentication is enabled for Non-secure world irrespective
- of the value of these build flags if the CPU supports it.
-
- If ``ARM_ARCH_MAJOR == 8`` and ``ARM_ARCH_MINOR >= 3`` the code footprint of
- enabling PAuth is lower because the compiler will use the optimized
- PAuth instructions rather than the backwards-compatible ones.
-
-Armv7-A
-~~~~~~~
-
-This Architecture Extension is targeted when ``ARM_ARCH_MAJOR`` == 7.
-
-There are several Armv7-A extensions available. Obviously the TrustZone
-extension is mandatory to support the TF-A bootloader and runtime services.
-
-Platform implementing an Armv7-A system can to define from its target
-Cortex-A architecture through ``ARM_CORTEX_A<X> = yes`` in their
-``platform.mk`` script. For example ``ARM_CORTEX_A15=yes`` for a
-Cortex-A15 target.
-
-Platform can also set ``ARM_WITH_NEON=yes`` to enable neon support.
-Note that using neon at runtime has constraints on non secure wolrd context.
-TF-A does not yet provide VFP context management.
-
-Directive ``ARM_CORTEX_A<x>`` and ``ARM_WITH_NEON`` are used to set
-the toolchain target architecture directive.
-
-Platform may choose to not define straight the toolchain target architecture
-directive by defining ``MARCH32_DIRECTIVE``.
-I.e:
-
-::
-
- MARCH32_DIRECTIVE := -mach=armv7-a
-
-Code Structure
---------------
-
-TF-A code is logically divided between the three boot loader stages mentioned
-in the previous sections. The code is also divided into the following
-categories (present as directories in the source code):
-
-- **Platform specific.** Choice of architecture specific code depends upon
- the platform.
-- **Common code.** This is platform and architecture agnostic code.
-- **Library code.** This code comprises of functionality commonly used by all
- other code. The PSCI implementation and other EL3 runtime frameworks reside
- as Library components.
-- **Stage specific.** Code specific to a boot stage.
-- **Drivers.**
-- **Services.** EL3 runtime services (eg: SPD). Specific SPD services
- reside in the ``services/spd`` directory (e.g. ``services/spd/tspd``).
-
-Each boot loader stage uses code from one or more of the above mentioned
-categories. Based upon the above, the code layout looks like this:
-
-::
-
- Directory Used by BL1? Used by BL2? Used by BL31?
- bl1 Yes No No
- bl2 No Yes No
- bl31 No No Yes
- plat Yes Yes Yes
- drivers Yes No Yes
- common Yes Yes Yes
- lib Yes Yes Yes
- services No No Yes
-
-The build system provides a non configurable build option IMAGE_BLx for each
-boot loader stage (where x = BL stage). e.g. for BL1 , IMAGE_BL1 will be
-defined by the build system. This enables TF-A to compile certain code only
-for specific boot loader stages
-
-All assembler files have the ``.S`` extension. The linker source files for each
-boot stage have the extension ``.ld.S``. These are processed by GCC to create the
-linker scripts which have the extension ``.ld``.
-
-FDTs provide a description of the hardware platform and are used by the Linux
-kernel at boot time. These can be found in the ``fdts`` directory.
-
-References
-----------
-
-.. [#] `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D)`_
-.. [#] `Power State Coordination Interface PDD`_
-.. [#] `SMC Calling Convention PDD`_
-.. [#] `TF-A Interrupt Management Design guide`_.
-
---------------
-
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _Reset Design: ./reset-design.rst
-.. _Porting Guide: ./porting-guide.rst
-.. _Firmware Update: ./firmware-update.rst
-.. _PSCI PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _SMC calling convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
-.. _PSCI Library integration guide: ./psci-lib-integration-guide.rst
-.. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _here: ./psci-lib-integration-guide.rst
-.. _cpu-specific-build-macros.rst: ./cpu-specific-build-macros.rst
-.. _CPUBM: ./cpu-specific-build-macros.rst
-.. _Arm ARM: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.e/index.html
-.. _User Guide: ./user-guide.rst
-.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
-.. _TF-A Interrupt Management Design guide: ./interrupt-framework-design.rst
-.. _Xlat_tables design: xlat-tables-lib-v2-design.rst
-.. _Exception Handling Framework: exception-handling.rst
-.. _ROMLIB Design: romlib-design.rst
-.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
-
-.. |Image 1| image:: diagrams/rt-svc-descs-layout.png?raw=true
+++ /dev/null
-Trusted Firmware-A - Firmware Update design guide
-=================================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
---------------
-
-Introduction
-------------
-
-This document describes the design of the Firmware Update (FWU) feature, which
-enables authenticated firmware to update firmware images from external
-interfaces such as USB, UART, SD-eMMC, NAND, NOR or Ethernet to SoC Non-Volatile
-memories such as NAND Flash, LPPDR2-NVM or any memory determined by the
-platform. This feature functions even when the current firmware in the system
-is corrupt or missing; it therefore may be used as a recovery mode. It may also
-be complemented by other, higher level firmware update software.
-
-FWU implements a specific part of the Trusted Board Boot Requirements (TBBR)
-specification, Arm DEN0006C-1. It should be used in conjunction with the
-`Trusted Board Boot`_ design document, which describes the image authentication
-parts of the Trusted Firmware-A (TF-A) TBBR implementation.
-
-Scope
-~~~~~
-
-This document describes the secure world FWU design. It is beyond its scope to
-describe how normal world FWU images should operate. To implement normal world
-FWU images, please refer to the "Non-Trusted Firmware Updater" requirements in
-the TBBR.
-
-FWU Overview
-------------
-
-The FWU boot flow is primarily mediated by BL1. Since BL1 executes in ROM, and
-it is usually desirable to minimize the amount of ROM code, the design allows
-some parts of FWU to be implemented in other secure and normal world images.
-Platform code may choose which parts are implemented in which images but the
-general expectation is:
-
-- BL1 handles:
-
- - Detection and initiation of the FWU boot flow.
- - Copying images from non-secure to secure memory
- - FWU image authentication
- - Context switching between the normal and secure world during the FWU
- process.
-
-- Other secure world FWU images handle platform initialization required by
- the FWU process.
-- Normal world FWU images handle loading of firmware images from external
- interfaces to non-secure memory.
-
-The primary requirements of the FWU feature are:
-
-#. Export a BL1 SMC interface to interoperate with other FWU images executing
- at other Exception Levels.
-#. Export a platform interface to provide FWU common code with the information
- it needs, and to enable platform specific FWU functionality. See the
- `Porting Guide`_ for details of this interface.
-
-TF-A uses abbreviated image terminology for FWU images like for other TF-A
-images. An overview of this terminology can be found `here`_.
-
-The following diagram shows the FWU boot flow for Arm development platforms.
-Arm CSS platforms like Juno have a System Control Processor (SCP), and these
-use all defined FWU images. Other platforms may use a subset of these.
-
-|Flow Diagram|
-
-Image Identification
---------------------
-
-Each FWU image and certificate is identified by a unique ID, defined by the
-platform, which BL1 uses to fetch an image descriptor (``image_desc_t``) via a
-call to ``bl1_plat_get_image_desc()``. The same ID is also used to prepare the
-Chain of Trust (Refer to the `Authentication Framework Design`_
-for more information).
-
-The image descriptor includes the following information:
-
-- Executable or non-executable image. This indicates whether the normal world
- is permitted to request execution of a secure world FWU image (after
- authentication). Secure world certificates and non-AP images are examples
- of non-executable images.
-- Secure or non-secure image. This indicates whether the image is
- authenticated/executed in secure or non-secure memory.
-- Image base address and size.
-- Image entry point configuration (an ``entry_point_info_t``).
-- FWU image state.
-
-BL1 uses the FWU image descriptors to:
-
-- Validate the arguments of FWU SMCs
-- Manage the state of the FWU process
-- Initialize the execution state of the next FWU image.
-
-FWU State Machine
------------------
-
-BL1 maintains state for each FWU image during FWU execution. FWU images at lower
-Exception Levels raise SMCs to invoke FWU functionality in BL1, which causes
-BL1 to update its FWU image state. The BL1 image states and valid state
-transitions are shown in the diagram below. Note that secure images have a more
-complex state machine than non-secure images.
-
-|FWU state machine|
-
-The following is a brief description of the supported states:
-
-- RESET: This is the initial state of every image at the start of FWU.
- Authentication failure also leads to this state. A secure
- image may yield to this state if it has completed execution.
- It can also be reached by using ``FWU_SMC_IMAGE_RESET``.
-
-- COPYING: This is the state of a secure image while BL1 is copying it
- in blocks from non-secure to secure memory.
-
-- COPIED: This is the state of a secure image when BL1 has completed
- copying it to secure memory.
-
-- AUTHENTICATED: This is the state of an image when BL1 has successfully
- authenticated it.
-
-- EXECUTED: This is the state of a secure, executable image when BL1 has
- passed execution control to it.
-
-- INTERRUPTED: This is the state of a secure, executable image after it has
- requested BL1 to resume normal world execution.
-
-BL1 SMC Interface
------------------
-
-BL1_SMC_CALL_COUNT
-~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x0
-
- Return:
- uint32_t
-
-This SMC returns the number of SMCs supported by BL1.
-
-BL1_SMC_UID
-~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x1
-
- Return:
- UUID : 32 bits in each of w0-w3 (or r0-r3 for AArch32 callers)
-
-This SMC returns the 128-bit `Universally Unique Identifier`_ for the
-BL1 SMC service.
-
-BL1_SMC_VERSION
-~~~~~~~~~~~~~~~
-
-::
-
- Argument:
- uint32_t function ID : 0x3
-
- Return:
- uint32_t : Bits [31:16] Major Version
- Bits [15:0] Minor Version
-
-This SMC returns the current version of the BL1 SMC service.
-
-BL1_SMC_RUN_IMAGE
-~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x4
- entry_point_info_t *ep_info
-
- Return:
- void
-
- Pre-conditions:
- if (normal world caller) synchronous exception
- if (ep_info not EL3) synchronous exception
-
-This SMC passes execution control to an EL3 image described by the provided
-``entry_point_info_t`` structure. In the normal TF-A boot flow, BL2 invokes
-this SMC for BL1 to pass execution control to BL31.
-
-FWU_SMC_IMAGE_COPY
-~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x10
- unsigned int image_id
- uintptr_t image_addr
- unsigned int block_size
- unsigned int image_size
-
- Return:
- int : 0 (Success)
- : -ENOMEM
- : -EPERM
-
- Pre-conditions:
- if (image_id is invalid) return -EPERM
- if (image_id is non-secure image) return -EPERM
- if (image_id state is not (RESET or COPYING)) return -EPERM
- if (secure world caller) return -EPERM
- if (image_addr + block_size overflows) return -ENOMEM
- if (image destination address + image_size overflows) return -ENOMEM
- if (source block is in secure memory) return -ENOMEM
- if (source block is not mapped into BL1) return -ENOMEM
- if (image_size > free secure memory) return -ENOMEM
- if (image overlaps another image) return -EPERM
-
-This SMC copies the secure image indicated by ``image_id`` from non-secure memory
-to secure memory for later authentication. The image may be copied in a single
-block or multiple blocks. In either case, the total size of the image must be
-provided in ``image_size`` when invoking this SMC for the first time for each
-image; it is ignored in subsequent calls (if any) for the same image.
-
-The ``image_addr`` and ``block_size`` specify the source memory block to copy from.
-The destination address is provided by the platform code.
-
-If ``block_size`` is greater than the amount of remaining bytes to copy for this
-image then the former is truncated to the latter. The copy operation is then
-considered as complete and the FWU state machine transitions to the "COPIED"
-state. If there is still more to copy, the FWU state machine stays in or
-transitions to the COPYING state (depending on the previous state).
-
-When using multiple blocks, the source blocks do not necessarily need to be in
-contiguous memory.
-
-Once the SMC is handled, BL1 returns from exception to the normal world caller.
-
-FWU_SMC_IMAGE_AUTH
-~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x11
- unsigned int image_id
- uintptr_t image_addr
- unsigned int image_size
-
- Return:
- int : 0 (Success)
- : -ENOMEM
- : -EPERM
- : -EAUTH
-
- Pre-conditions:
- if (image_id is invalid) return -EPERM
- if (secure world caller)
- if (image_id state is not RESET) return -EPERM
- if (image_addr/image_size is not mapped into BL1) return -ENOMEM
- else // normal world caller
- if (image_id is secure image)
- if (image_id state is not COPIED) return -EPERM
- else // image_id is non-secure image
- if (image_id state is not RESET) return -EPERM
- if (image_addr/image_size is in secure memory) return -ENOMEM
- if (image_addr/image_size not mapped into BL1) return -ENOMEM
-
-This SMC authenticates the image specified by ``image_id``. If the image is in the
-RESET state, BL1 authenticates the image in place using the provided
-``image_addr`` and ``image_size``. If the image is a secure image in the COPIED
-state, BL1 authenticates the image from the secure memory that BL1 previously
-copied the image into.
-
-BL1 returns from exception to the caller. If authentication succeeds then BL1
-sets the image state to AUTHENTICATED. If authentication fails then BL1 returns
-the -EAUTH error and sets the image state back to RESET.
-
-FWU_SMC_IMAGE_EXECUTE
-~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x12
- unsigned int image_id
-
- Return:
- int : 0 (Success)
- : -EPERM
-
- Pre-conditions:
- if (image_id is invalid) return -EPERM
- if (secure world caller) return -EPERM
- if (image_id is non-secure image) return -EPERM
- if (image_id is non-executable image) return -EPERM
- if (image_id state is not AUTHENTICATED) return -EPERM
-
-This SMC initiates execution of a previously authenticated image specified by
-``image_id``, in the other security world to the caller. The current
-implementation only supports normal world callers initiating execution of a
-secure world image.
-
-BL1 saves the normal world caller's context, sets the secure image state to
-EXECUTED, and returns from exception to the secure image.
-
-FWU_SMC_IMAGE_RESUME
-~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x13
- register_t image_param
-
- Return:
- register_t : image_param (Success)
- : -EPERM
-
- Pre-conditions:
- if (normal world caller and no INTERRUPTED secure image) return -EPERM
-
-This SMC resumes execution in the other security world while there is a secure
-image in the EXECUTED/INTERRUPTED state.
-
-For normal world callers, BL1 sets the previously interrupted secure image state
-to EXECUTED. For secure world callers, BL1 sets the previously executing secure
-image state to INTERRUPTED. In either case, BL1 saves the calling world's
-context, restores the resuming world's context and returns from exception into
-the resuming world. If the call is successful then the caller provided
-``image_param`` is returned to the resumed world, otherwise an error code is
-returned to the caller.
-
-FWU_SMC_SEC_IMAGE_DONE
-~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x14
-
- Return:
- int : 0 (Success)
- : -EPERM
-
- Pre-conditions:
- if (normal world caller) return -EPERM
-
-This SMC indicates completion of a previously executing secure image.
-
-BL1 sets the previously executing secure image state to the RESET state,
-restores the normal world context and returns from exception into the normal
-world.
-
-FWU_SMC_UPDATE_DONE
-~~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x15
- register_t client_cookie
-
- Return:
- N/A
-
-This SMC completes the firmware update process. BL1 calls the platform specific
-function ``bl1_plat_fwu_done``, passing the optional argument ``client_cookie`` as
-a ``void *``. The SMC does not return.
-
-FWU_SMC_IMAGE_RESET
-~~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments:
- uint32_t function ID : 0x16
- unsigned int image_id
-
- Return:
- int : 0 (Success)
- : -EPERM
-
- Pre-conditions:
- if (secure world caller) return -EPERM
- if (image in EXECUTED) return -EPERM
-
-This SMC sets the state of an image to RESET and zeroes the memory used by it.
-
-This is only allowed if the image is not being executed.
-
---------------
-
-*Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _Trusted Board Boot: ./trusted-board-boot.rst
-.. _Porting Guide: ./porting-guide.rst
-.. _here: https://github.com/ARM-software/arm-trusted-firmware/wiki/ARM-Trusted-Firmware-Image-Terminology
-.. _Authentication Framework Design: ./auth-framework.rst
-.. _Universally Unique Identifier: https://tools.ietf.org/rfc/rfc4122.txt
-
-.. |Flow Diagram| image:: diagrams/fwu_flow.png?raw=true
-.. |FWU state machine| image:: diagrams/fwu_states.png?raw=true
+++ /dev/null
-Frequently-Asked Questions (FAQ)
-================================
-
-How do I update my changes?
----------------------------
-
-Often it is necessary to update your patch set before it is merged. Refer to the
-`Gerrit Upload Patch Set documentation`_ on how to do so.
-
-If you need to modify an existing patch set with multiple commits, refer to the
-`Gerrit Replace Changes documentation`_.
-
-How long will my changes take to merge into ``integration``?
-------------------------------------------------------------
-
-This can vary a lot, depending on:
-
-* How important the patch set is considered by the TF maintainers. Where
- possible, you should indicate the required timescales for merging the patch
- set and the impact of any delay. Feel free to add a comment to your patch set
- to get an estimate of when it will be merged.
-
-* The quality of the patch set. Patches are likely to be merged more quickly if
- they follow the coding guidelines, have already had some code review, and have
- been appropriately tested.
-
-* The impact of the patch set. For example, a patch that changes a key generic
- API is likely to receive much greater scrutiny than a local change to a
- specific platform port.
-
-* How much opportunity for external review is required. For example, the TF
- maintainers may not wait for external review comments to merge trivial
- bug-fixes but may wait up to a week to merge major changes, or ones requiring
- feedback from specific parties.
-
-* How many other patch sets are waiting to be integrated and the risk of
- conflict between the topics.
-
-* If there is a code freeze in place in preparation for the release. Please
- refer the `release information`_ for more details.
-
-* The workload of the TF maintainers.
-
-How long will it take for my changes to go from ``integration`` to ``master``?
-------------------------------------------------------------------------------
-
-This depends on how many concurrent patches are being processed at the same
-time. In simple cases where all potential regressions have already been tested,
-the delay will be less than 1 day. If the TF maintainers are trying to merge
-several things over the course of a few days, it might take up to a week.
-Typically, it will be 1-2 days.
-
-The worst case is if the TF maintainers are trying to make a release while also
-receiving patches that will not be merged into the release. In this case, the
-patches will be merged onto ``integration``, which will temporarily diverge from
-the release branch. The ``integration`` branch will be rebased onto ``master``
-after the release, and then ``master`` will be fast-forwarded to ``integration``
-1-2 days later. This whole process could take up 4 weeks. Please refer the
-`release information`_ for code freeze dates. The TF maintainers will inform the
-patch owner if this is going to happen.
-
-It is OK to create a patch based on commits that are only available in
-``integration`` or another patch set, rather than ``master``. There is a risk
-that the dependency commits will change (for example due to patch set rework or
-integration problems). If this happens, the dependent patch will need reworking.
-
-What are these strange comments in my changes?
-----------------------------------------------
-
-All the comments from ``ci-bot-user`` are associated with Continuous Integration
-infrastructure. The links published on the comment are not currently accessible,
-but would be after the CI has been transitioned to `trustedfirmware.org`_.
-Please refer to https://github.com/ARM-software/tf-issues/issues/681 for more
-details on the timelines.
-
-.. _release information: release-information.rst
-.. _Gerrit Upload Patch Set documentation: https://review.trustedfirmware.org/Documentation/intro-user.html#upload-patch-set
-.. _Gerrit Replace Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html#push_replace
-.. _trustedfirmware.org: https://www.trustedfirmware.org/
--- /dev/null
+Image Terminology
+=================
+
+.. section-numbering::
+ :suffix: .
+
+.. contents::
+
+This page contains the current name, abbreviated name and purpose of the various
+images referred to in the Trusted Firmware project.
+
+General Notes
+-------------
+
+- Some of the names and abbreviated names have changed to accomodate new
+ requirements. The changed names are as backward compatible as possible to
+ minimize confusion. Where applicable, the previous names are indicated. Some
+ code, documentation and build artefacts may still refer to the previous names;
+ these will inevitably take time to catch up.
+
+- The main name change is to prefix each image with the processor it corresponds
+ to (for example ``AP_``, ``SCP_``, ...). In situations where there is no
+ ambiguity (for example, within AP specific code/documentation), it is
+ permitted to omit the processor prefix (for example, just BL1 instead of
+ ``AP_BL1``).
+
+- Previously, the format for 3rd level images had 2 forms; ``BL3`` was either
+ suffixed with a dash ("-") followed by a number (for example, ``BL3-1``) or a
+ subscript number, depending on whether rich text formatting was available.
+ This was confusing and often the dash gets omitted in practice. Therefore the
+ new form is to just omit the dash and not use subscript formatting.
+
+- The names no longer contain dash ("-") characters at all. In some places (for
+ example, function names) it's not possible to use this character. All dashes
+ are either removed or replaced by underscores ("_").
+
+- The abbreviation BL stands for BootLoader. This is a historical anomaly.
+ Clearly, many of these images are not BootLoaders, they are simply firmware
+ images. However, the BL abbreviation is now widely used and is retained for
+ backwards compatibility.
+
+- The image names are not case sensitive. For example, ``bl1`` is
+ interchangeable with ``BL1``, although mixed case should be avoided.
+
+Trusted Firmware Images
+-----------------------
+
+AP Boot ROM: ``AP_BL1``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Typically, this is the first code to execute on the AP and cannot be modified.
+Its primary purpose is to perform the minimum intialization necessary to load
+and authenticate an updateable AP firmware image into an executable RAM
+location, then hand-off control to that image.
+
+AP RAM Firmware: ``AP_BL2``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is the 2nd stage AP firmware. It is currently also known as the "Trusted
+Boot Firmware". Its primary purpose is to perform any additional initialization
+required to load and authenticate all 3rd level firmware images into their
+executable RAM locations, then hand-off control to the EL3 Runtime Firmware.
+
+EL3 Runtime Firmware: ``AP_BL31``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Also known as "SoC AP firmware" or "EL3 monitor firmware". Its primary purpose
+is to handle transitions between the normal and secure world.
+
+Secure-EL1 Payload (SP): ``AP_BL32``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Typically this is a TEE or Trusted OS, providing runtime secure services to the
+normal world. However, it may refer to a more abstract Secure-EL1 Payload (SP).
+Note that this abbreviation should only be used in systems where there is a
+single or primary image executing at Secure-EL1. In systems where there are
+potentially multiple SPs and there is no concept of a primary SP, this
+abbreviation should be avoided; use the recommended **Other AP 3rd level
+images** abbreviation instead.
+
+AP Normal World Firmware: ``AP_BL33``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For example, UEFI or uboot. Its primary purpose is to boot a normal world OS.
+
+Other AP 3rd level images: ``AP_BL3_XXX``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The abbreviated names of the existing 3rd level images imply a load/execution
+ordering (for example, ``AP_BL31 -> AP_BL32 -> AP_BL33``). Some systems may
+have additional images and/or a different load/execution ordering. The
+abbreviated names of the existing images are retained for backward compatibility
+but new 3rd level images should be suffixed with an underscore followed by text
+identifier, not a number.
+
+In systems where 3rd level images are provided by different vendors, the
+abbreviated name should identify the vendor as well as the image
+function. For example, ``AP_BL3_ARM_RAS``.
+
+SCP Boot ROM: ``SCP_BL1`` (previously ``BL0``)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Typically, this is the first code to execute on the SCP and cannot be modified.
+Its primary purpose is to perform the minimum intialization necessary to load
+and authenticate an updateable SCP firmware image into an executable RAM
+location, then hand-off control to that image. This may be performed in
+conjunction with other processor firmware (for example, ``AP_BL1`` and
+``AP_BL2``).
+
+This image was previously abbreviated as ``BL0`` but in some systems, the SCP
+may directly load/authenticate its own firmware. In these systems, it doesn't
+make sense to interleave the image terminology for AP and SCP; both AP and SCP
+Boot ROMs are ``BL1`` from their own point of view.
+
+SCP RAM Firmware: ``SCP_BL2`` (previously ``BL3-0``)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is the 2nd stage SCP firmware. It is currently also known as the "SCP
+runtime firmware" but it could potentially be an intermediate firmware if the
+SCP needs to load/authenticate multiple 3rd level images in future.
+
+This image was previously abbreviated as BL3-0 but from the SCP's point of view,
+this has always been the 2nd stage firmware. The previous name is too
+AP-centric.
+
+Firmware Update (FWU) Images
+----------------------------
+
+The terminology for these images has not been widely adopted yet but they have
+to be considered in a production Trusted Board Boot solution.
+
+AP Firmware Update Boot ROM: ``AP_NS_BL1U``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Typically, this is the first normal world code to execute on the AP during a
+firmware update operation, and cannot be modified. Its primary purpose is to
+load subequent firmware update images from an external interface and communicate
+with ``AP_BL1`` to authenticate those images.
+
+During firmware update, there are (potentially) multiple transitions between the
+secure and normal world. The "level" of the BL image is relative to the world
+it's in so it makes sense to encode "NS" in the normal world images. The absence
+of "NS" implies a secure world image.
+
+AP Firmware Update Config: ``AP_BL2U``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This image does the minimum necessary AP secure world configuration required to
+complete the firmware update operation. It is potentially a subset of ``AP_BL2``
+functionality.
+
+SCP Firmware Update Config: ``SCP_BL2U`` (previously ``BL2-U0``)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This image does the minimum necessary SCP secure world configuration required to
+complete the firmware update operation. It is potentially a subset of
+``SCP_BL2`` functionality.
+
+AP Firmware Updater: ``AP_NS_BL2U`` (previously ``BL3-U``)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is the 2nd stage AP normal world firmware updater. Its primary purpose is
+to load a new set of firmware images from an external interface and write them
+into non-volatile storage.
+
+Other Processor Firmware Images
+-------------------------------
+
+Some systems may have additional processors to the AP and SCP. For example, a
+Management Control Processor (MCP). Images for these processors should follow
+the same terminology, with the processor abbreviation prefix, followed by
+underscore and the level of the firmware image.
+
+For example,
+
+MCP Boot ROM: ``MCP_BL1``
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+MCP RAM Firmware: ``MCP_BL2``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- /dev/null
+Getting Started
+===============
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+ :numbered:
+
+ user-guide
+ image-terminology
+ porting-guide
+ psci-lib-integration-guide
+ rt-svc-writers-guide
--- /dev/null
+Trusted Firmware-A Porting Guide
+================================
+
+
+
+.. contents::
+
+Introduction
+------------
+
+Porting Trusted Firmware-A (TF-A) to a new platform involves making some
+mandatory and optional modifications for both the cold and warm boot paths.
+Modifications consist of:
+
+- Implementing a platform-specific function or variable,
+- Setting up the execution context in a certain way, or
+- Defining certain constants (for example #defines).
+
+The platform-specific functions and variables are declared in
+`include/plat/common/platform.h`_. The firmware provides a default implementation
+of variables and functions to fulfill the optional requirements. These
+implementations are all weakly defined; they are provided to ease the porting
+effort. Each platform port can override them with its own implementation if the
+default implementation is inadequate.
+
+Some modifications are common to all Boot Loader (BL) stages. Section 2
+discusses these in detail. The subsequent sections discuss the remaining
+modifications for each BL stage in detail.
+
+This document should be read in conjunction with the TF-A `User Guide`_.
+
+Please refer to the `Platform compatibility policy`_ for the policy regarding
+compatibility and deprecation of these porting interfaces.
+
+Only Arm development platforms (such as FVP and Juno) may use the
+functions/definitions in ``include/plat/arm/common/`` and the corresponding
+source files in ``plat/arm/common/``. This is done so that there are no
+dependencies between platforms maintained by different people/companies. If you
+want to use any of the functionality present in ``plat/arm`` files, please
+create a pull request that moves the code to ``plat/common`` so that it can be
+discussed.
+
+Common modifications
+--------------------
+
+This section covers the modifications that should be made by the platform for
+each BL stage to correctly port the firmware stack. They are categorized as
+either mandatory or optional.
+
+Common mandatory modifications
+------------------------------
+
+A platform port must enable the Memory Management Unit (MMU) as well as the
+instruction and data caches for each BL stage. Setting up the translation
+tables is the responsibility of the platform port because memory maps differ
+across platforms. A memory translation library (see ``lib/xlat_tables/``) is
+provided to help in this setup.
+
+Note that although this library supports non-identity mappings, this is intended
+only for re-mapping peripheral physical addresses and allows platforms with high
+I/O addresses to reduce their virtual address space. All other addresses
+corresponding to code and data must currently use an identity mapping.
+
+Also, the only translation granule size supported in TF-A is 4KB, as various
+parts of the code assume that is the case. It is not possible to switch to
+16 KB or 64 KB granule sizes at the moment.
+
+In Arm standard platforms, each BL stage configures the MMU in the
+platform-specific architecture setup function, ``blX_plat_arch_setup()``, and uses
+an identity mapping for all addresses.
+
+If the build option ``USE_COHERENT_MEM`` is enabled, each platform can allocate a
+block of identity mapped secure memory with Device-nGnRE attributes aligned to
+page boundary (4K) for each BL stage. All sections which allocate coherent
+memory are grouped under ``coherent_ram``. For ex: Bakery locks are placed in a
+section identified by name ``bakery_lock`` inside ``coherent_ram`` so that its
+possible for the firmware to place variables in it using the following C code
+directive:
+
+::
+
+ __section("bakery_lock")
+
+Or alternatively the following assembler code directive:
+
+::
+
+ .section bakery_lock
+
+The ``coherent_ram`` section is a sum of all sections like ``bakery_lock`` which are
+used to allocate any data structures that are accessed both when a CPU is
+executing with its MMU and caches enabled, and when it's running with its MMU
+and caches disabled. Examples are given below.
+
+The following variables, functions and constants must be defined by the platform
+for the firmware to work correctly.
+
+File : platform_def.h [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each platform must ensure that a header file of this name is in the system
+include path with the following constants defined. This will require updating
+the list of ``PLAT_INCLUDES`` in the ``platform.mk`` file.
+
+Platform ports may optionally use the file `include/plat/common/common_def.h`_,
+which provides typical values for some of the constants below. These values are
+likely to be suitable for all platform ports.
+
+- **#define : PLATFORM_LINKER_FORMAT**
+
+ Defines the linker format used by the platform, for example
+ ``elf64-littleaarch64``.
+
+- **#define : PLATFORM_LINKER_ARCH**
+
+ Defines the processor architecture for the linker by the platform, for
+ example ``aarch64``.
+
+- **#define : PLATFORM_STACK_SIZE**
+
+ Defines the normal stack memory available to each CPU. This constant is used
+ by `plat/common/aarch64/platform_mp_stack.S`_ and
+ `plat/common/aarch64/platform_up_stack.S`_.
+
+- **define : CACHE_WRITEBACK_GRANULE**
+
+ Defines the size in bits of the largest cache line across all the cache
+ levels in the platform.
+
+- **#define : FIRMWARE_WELCOME_STR**
+
+ Defines the character string printed by BL1 upon entry into the ``bl1_main()``
+ function.
+
+- **#define : PLATFORM_CORE_COUNT**
+
+ Defines the total number of CPUs implemented by the platform across all
+ clusters in the system.
+
+- **#define : PLAT_NUM_PWR_DOMAINS**
+
+ Defines the total number of nodes in the power domain topology
+ tree at all the power domain levels used by the platform.
+ This macro is used by the PSCI implementation to allocate
+ data structures to represent power domain topology.
+
+- **#define : PLAT_MAX_PWR_LVL**
+
+ Defines the maximum power domain level that the power management operations
+ should apply to. More often, but not always, the power domain level
+ corresponds to affinity level. This macro allows the PSCI implementation
+ to know the highest power domain level that it should consider for power
+ management operations in the system that the platform implements. For
+ example, the Base AEM FVP implements two clusters with a configurable
+ number of CPUs and it reports the maximum power domain level as 1.
+
+- **#define : PLAT_MAX_OFF_STATE**
+
+ Defines the local power state corresponding to the deepest power down
+ possible at every power domain level in the platform. The local power
+ states for each level may be sparsely allocated between 0 and this value
+ with 0 being reserved for the RUN state. The PSCI implementation uses this
+ value to initialize the local power states of the power domain nodes and
+ to specify the requested power state for a PSCI_CPU_OFF call.
+
+- **#define : PLAT_MAX_RET_STATE**
+
+ Defines the local power state corresponding to the deepest retention state
+ possible at every power domain level in the platform. This macro should be
+ a value less than PLAT_MAX_OFF_STATE and greater than 0. It is used by the
+ PSCI implementation to distinguish between retention and power down local
+ power states within PSCI_CPU_SUSPEND call.
+
+- **#define : PLAT_MAX_PWR_LVL_STATES**
+
+ Defines the maximum number of local power states per power domain level
+ that the platform supports. The default value of this macro is 2 since
+ most platforms just support a maximum of two local power states at each
+ power domain level (power-down and retention). If the platform needs to
+ account for more local power states, then it must redefine this macro.
+
+ Currently, this macro is used by the Generic PSCI implementation to size
+ the array used for PSCI_STAT_COUNT/RESIDENCY accounting.
+
+- **#define : BL1_RO_BASE**
+
+ Defines the base address in secure ROM where BL1 originally lives. Must be
+ aligned on a page-size boundary.
+
+- **#define : BL1_RO_LIMIT**
+
+ Defines the maximum address in secure ROM that BL1's actual content (i.e.
+ excluding any data section allocated at runtime) can occupy.
+
+- **#define : BL1_RW_BASE**
+
+ Defines the base address in secure RAM where BL1's read-write data will live
+ at runtime. Must be aligned on a page-size boundary.
+
+- **#define : BL1_RW_LIMIT**
+
+ Defines the maximum address in secure RAM that BL1's read-write data can
+ occupy at runtime.
+
+- **#define : BL2_BASE**
+
+ Defines the base address in secure RAM where BL1 loads the BL2 binary image.
+ Must be aligned on a page-size boundary. This constant is not applicable
+ when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2_LIMIT**
+
+ Defines the maximum address in secure RAM that the BL2 image can occupy.
+ This constant is not applicable when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2_RO_BASE**
+
+ Defines the base address in secure XIP memory where BL2 RO section originally
+ lives. Must be aligned on a page-size boundary. This constant is only needed
+ when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2_RO_LIMIT**
+
+ Defines the maximum address in secure XIP memory that BL2's actual content
+ (i.e. excluding any data section allocated at runtime) can occupy. This
+ constant is only needed when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2_RW_BASE**
+
+ Defines the base address in secure RAM where BL2's read-write data will live
+ at runtime. Must be aligned on a page-size boundary. This constant is only
+ needed when BL2_IN_XIP_MEM is set to '1'.
+
+- **#define : BL2_RW_LIMIT**
+
+ Defines the maximum address in secure RAM that BL2's read-write data can
+ occupy at runtime. This constant is only needed when BL2_IN_XIP_MEM is set
+ to '1'.
+
+- **#define : BL31_BASE**
+
+ Defines the base address in secure RAM where BL2 loads the BL31 binary
+ image. Must be aligned on a page-size boundary.
+
+- **#define : BL31_LIMIT**
+
+ Defines the maximum address in secure RAM that the BL31 image can occupy.
+
+For every image, the platform must define individual identifiers that will be
+used by BL1 or BL2 to load the corresponding image into memory from non-volatile
+storage. For the sake of performance, integer numbers will be used as
+identifiers. The platform will use those identifiers to return the relevant
+information about the image to be loaded (file handler, load address,
+authentication information, etc.). The following image identifiers are
+mandatory:
+
+- **#define : BL2_IMAGE_ID**
+
+ BL2 image identifier, used by BL1 to load BL2.
+
+- **#define : BL31_IMAGE_ID**
+
+ BL31 image identifier, used by BL2 to load BL31.
+
+- **#define : BL33_IMAGE_ID**
+
+ BL33 image identifier, used by BL2 to load BL33.
+
+If Trusted Board Boot is enabled, the following certificate identifiers must
+also be defined:
+
+- **#define : TRUSTED_BOOT_FW_CERT_ID**
+
+ BL2 content certificate identifier, used by BL1 to load the BL2 content
+ certificate.
+
+- **#define : TRUSTED_KEY_CERT_ID**
+
+ Trusted key certificate identifier, used by BL2 to load the trusted key
+ certificate.
+
+- **#define : SOC_FW_KEY_CERT_ID**
+
+ BL31 key certificate identifier, used by BL2 to load the BL31 key
+ certificate.
+
+- **#define : SOC_FW_CONTENT_CERT_ID**
+
+ BL31 content certificate identifier, used by BL2 to load the BL31 content
+ certificate.
+
+- **#define : NON_TRUSTED_FW_KEY_CERT_ID**
+
+ BL33 key certificate identifier, used by BL2 to load the BL33 key
+ certificate.
+
+- **#define : NON_TRUSTED_FW_CONTENT_CERT_ID**
+
+ BL33 content certificate identifier, used by BL2 to load the BL33 content
+ certificate.
+
+- **#define : FWU_CERT_ID**
+
+ Firmware Update (FWU) certificate identifier, used by NS_BL1U to load the
+ FWU content certificate.
+
+- **#define : PLAT_CRYPTOCELL_BASE**
+
+ This defines the base address of Arm® TrustZone® CryptoCell and must be
+ defined if CryptoCell crypto driver is used for Trusted Board Boot. For
+ capable Arm platforms, this driver is used if ``ARM_CRYPTOCELL_INTEG`` is
+ set.
+
+If the AP Firmware Updater Configuration image, BL2U is used, the following
+must also be defined:
+
+- **#define : BL2U_BASE**
+
+ Defines the base address in secure memory where BL1 copies the BL2U binary
+ image. Must be aligned on a page-size boundary.
+
+- **#define : BL2U_LIMIT**
+
+ Defines the maximum address in secure memory that the BL2U image can occupy.
+
+- **#define : BL2U_IMAGE_ID**
+
+ BL2U image identifier, used by BL1 to fetch an image descriptor
+ corresponding to BL2U.
+
+If the SCP Firmware Update Configuration Image, SCP_BL2U is used, the following
+must also be defined:
+
+- **#define : SCP_BL2U_IMAGE_ID**
+
+ SCP_BL2U image identifier, used by BL1 to fetch an image descriptor
+ corresponding to SCP_BL2U.
+ NOTE: TF-A does not provide source code for this image.
+
+If the Non-Secure Firmware Updater ROM, NS_BL1U is used, the following must
+also be defined:
+
+- **#define : NS_BL1U_BASE**
+
+ Defines the base address in non-secure ROM where NS_BL1U executes.
+ Must be aligned on a page-size boundary.
+ NOTE: TF-A does not provide source code for this image.
+
+- **#define : NS_BL1U_IMAGE_ID**
+
+ NS_BL1U image identifier, used by BL1 to fetch an image descriptor
+ corresponding to NS_BL1U.
+
+If the Non-Secure Firmware Updater, NS_BL2U is used, the following must also
+be defined:
+
+- **#define : NS_BL2U_BASE**
+
+ Defines the base address in non-secure memory where NS_BL2U executes.
+ Must be aligned on a page-size boundary.
+ NOTE: TF-A does not provide source code for this image.
+
+- **#define : NS_BL2U_IMAGE_ID**
+
+ NS_BL2U image identifier, used by BL1 to fetch an image descriptor
+ corresponding to NS_BL2U.
+
+For the the Firmware update capability of TRUSTED BOARD BOOT, the following
+macros may also be defined:
+
+- **#define : PLAT_FWU_MAX_SIMULTANEOUS_IMAGES**
+
+ Total number of images that can be loaded simultaneously. If the platform
+ doesn't specify any value, it defaults to 10.
+
+If a SCP_BL2 image is supported by the platform, the following constants must
+also be defined:
+
+- **#define : SCP_BL2_IMAGE_ID**
+
+ SCP_BL2 image identifier, used by BL2 to load SCP_BL2 into secure memory
+ from platform storage before being transferred to the SCP.
+
+- **#define : SCP_FW_KEY_CERT_ID**
+
+ SCP_BL2 key certificate identifier, used by BL2 to load the SCP_BL2 key
+ certificate (mandatory when Trusted Board Boot is enabled).
+
+- **#define : SCP_FW_CONTENT_CERT_ID**
+
+ SCP_BL2 content certificate identifier, used by BL2 to load the SCP_BL2
+ content certificate (mandatory when Trusted Board Boot is enabled).
+
+If a BL32 image is supported by the platform, the following constants must
+also be defined:
+
+- **#define : BL32_IMAGE_ID**
+
+ BL32 image identifier, used by BL2 to load BL32.
+
+- **#define : TRUSTED_OS_FW_KEY_CERT_ID**
+
+ BL32 key certificate identifier, used by BL2 to load the BL32 key
+ certificate (mandatory when Trusted Board Boot is enabled).
+
+- **#define : TRUSTED_OS_FW_CONTENT_CERT_ID**
+
+ BL32 content certificate identifier, used by BL2 to load the BL32 content
+ certificate (mandatory when Trusted Board Boot is enabled).
+
+- **#define : BL32_BASE**
+
+ Defines the base address in secure memory where BL2 loads the BL32 binary
+ image. Must be aligned on a page-size boundary.
+
+- **#define : BL32_LIMIT**
+
+ Defines the maximum address that the BL32 image can occupy.
+
+If the Test Secure-EL1 Payload (TSP) instantiation of BL32 is supported by the
+platform, the following constants must also be defined:
+
+- **#define : TSP_SEC_MEM_BASE**
+
+ Defines the base address of the secure memory used by the TSP image on the
+ platform. This must be at the same address or below ``BL32_BASE``.
+
+- **#define : TSP_SEC_MEM_SIZE**
+
+ Defines the size of the secure memory used by the BL32 image on the
+ platform. ``TSP_SEC_MEM_BASE`` and ``TSP_SEC_MEM_SIZE`` must fully
+ accommodate the memory required by the BL32 image, defined by ``BL32_BASE``
+ and ``BL32_LIMIT``.
+
+- **#define : TSP_IRQ_SEC_PHY_TIMER**
+
+ Defines the ID of the secure physical generic timer interrupt used by the
+ TSP's interrupt handling code.
+
+If the platform port uses the translation table library code, the following
+constants must also be defined:
+
+- **#define : PLAT_XLAT_TABLES_DYNAMIC**
+
+ Optional flag that can be set per-image to enable the dynamic allocation of
+ regions even when the MMU is enabled. If not defined, only static
+ functionality will be available, if defined and set to 1 it will also
+ include the dynamic functionality.
+
+- **#define : MAX_XLAT_TABLES**
+
+ Defines the maximum number of translation tables that are allocated by the
+ translation table library code. To minimize the amount of runtime memory
+ used, choose the smallest value needed to map the required virtual addresses
+ for each BL stage. If ``PLAT_XLAT_TABLES_DYNAMIC`` flag is enabled for a BL
+ image, ``MAX_XLAT_TABLES`` must be defined to accommodate the dynamic regions
+ as well.
+
+- **#define : MAX_MMAP_REGIONS**
+
+ Defines the maximum number of regions that are allocated by the translation
+ table library code. A region consists of physical base address, virtual base
+ address, size and attributes (Device/Memory, RO/RW, Secure/Non-Secure), as
+ defined in the ``mmap_region_t`` structure. The platform defines the regions
+ that should be mapped. Then, the translation table library will create the
+ corresponding tables and descriptors at runtime. To minimize the amount of
+ runtime memory used, choose the smallest value needed to register the
+ required regions for each BL stage. If ``PLAT_XLAT_TABLES_DYNAMIC`` flag is
+ enabled for a BL image, ``MAX_MMAP_REGIONS`` must be defined to accommodate
+ the dynamic regions as well.
+
+- **#define : PLAT_VIRT_ADDR_SPACE_SIZE**
+
+ Defines the total size of the virtual address space in bytes. For example,
+ for a 32 bit virtual address space, this value should be ``(1ULL << 32)``.
+
+- **#define : PLAT_PHY_ADDR_SPACE_SIZE**
+
+ Defines the total size of the physical address space in bytes. For example,
+ for a 32 bit physical address space, this value should be ``(1ULL << 32)``.
+
+If the platform port uses the IO storage framework, the following constants
+must also be defined:
+
+- **#define : MAX_IO_DEVICES**
+
+ Defines the maximum number of registered IO devices. Attempting to register
+ more devices than this value using ``io_register_device()`` will fail with
+ -ENOMEM.
+
+- **#define : MAX_IO_HANDLES**
+
+ Defines the maximum number of open IO handles. Attempting to open more IO
+ entities than this value using ``io_open()`` will fail with -ENOMEM.
+
+- **#define : MAX_IO_BLOCK_DEVICES**
+
+ Defines the maximum number of registered IO block devices. Attempting to
+ register more devices this value using ``io_dev_open()`` will fail
+ with -ENOMEM. MAX_IO_BLOCK_DEVICES should be less than MAX_IO_DEVICES.
+ With this macro, multiple block devices could be supported at the same
+ time.
+
+If the platform needs to allocate data within the per-cpu data framework in
+BL31, it should define the following macro. Currently this is only required if
+the platform decides not to use the coherent memory section by undefining the
+``USE_COHERENT_MEM`` build flag. In this case, the framework allocates the
+required memory within the the per-cpu data to minimize wastage.
+
+- **#define : PLAT_PCPU_DATA_SIZE**
+
+ Defines the memory (in bytes) to be reserved within the per-cpu data
+ structure for use by the platform layer.
+
+The following constants are optional. They should be defined when the platform
+memory layout implies some image overlaying like in Arm standard platforms.
+
+- **#define : BL31_PROGBITS_LIMIT**
+
+ Defines the maximum address in secure RAM that the BL31's progbits sections
+ can occupy.
+
+- **#define : TSP_PROGBITS_LIMIT**
+
+ Defines the maximum address that the TSP's progbits sections can occupy.
+
+If the platform port uses the PL061 GPIO driver, the following constant may
+optionally be defined:
+
+- **PLAT_PL061_MAX_GPIOS**
+ Maximum number of GPIOs required by the platform. This allows control how
+ much memory is allocated for PL061 GPIO controllers. The default value is
+
+ #. $(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
+
+If the platform port uses the partition driver, the following constant may
+optionally be defined:
+
+- **PLAT_PARTITION_MAX_ENTRIES**
+ Maximum number of partition entries required by the platform. This allows
+ control how much memory is allocated for partition entries. The default
+ value is 128.
+ `For example, define the build flag in platform.mk`_:
+ PLAT_PARTITION_MAX_ENTRIES := 12
+ $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
+
+The following constant is optional. It should be defined to override the default
+behaviour of the ``assert()`` function (for example, to save memory).
+
+- **PLAT_LOG_LEVEL_ASSERT**
+ If ``PLAT_LOG_LEVEL_ASSERT`` is higher or equal than ``LOG_LEVEL_VERBOSE``,
+ ``assert()`` prints the name of the file, the line number and the asserted
+ expression. Else if it is higher than ``LOG_LEVEL_INFO``, it prints the file
+ name and the line number. Else if it is lower than ``LOG_LEVEL_INFO``, it
+ doesn't print anything to the console. If ``PLAT_LOG_LEVEL_ASSERT`` isn't
+ defined, it defaults to ``LOG_LEVEL``.
+
+If the platform port uses the Activity Monitor Unit, the following constants
+may be defined:
+
+- **PLAT_AMU_GROUP1_COUNTERS_MASK**
+ This mask reflects the set of group counters that should be enabled. The
+ maximum number of group 1 counters supported by AMUv1 is 16 so the mask
+ can be at most 0xffff. If the platform does not define this mask, no group 1
+ counters are enabled. If the platform defines this mask, the following
+ constant needs to also be defined.
+
+- **PLAT_AMU_GROUP1_NR_COUNTERS**
+ This value is used to allocate an array to save and restore the counters
+ specified by ``PLAT_AMU_GROUP1_COUNTERS_MASK`` on CPU suspend.
+ This value should be equal to the highest bit position set in the
+ mask, plus 1. The maximum number of group 1 counters in AMUv1 is 16.
+
+File : plat_macros.S [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each platform must ensure a file of this name is in the system include path with
+the following macro defined. In the Arm development platforms, this file is
+found in ``plat/arm/board/<plat_name>/include/plat_macros.S``.
+
+- **Macro : plat_crash_print_regs**
+
+ This macro allows the crash reporting routine to print relevant platform
+ registers in case of an unhandled exception in BL31. This aids in debugging
+ and this macro can be defined to be empty in case register reporting is not
+ desired.
+
+ For instance, GIC or interconnect registers may be helpful for
+ troubleshooting.
+
+Handling Reset
+--------------
+
+BL1 by default implements the reset vector where execution starts from a cold
+or warm boot. BL31 can be optionally set as a reset vector using the
+``RESET_TO_BL31`` make variable.
+
+For each CPU, the reset vector code is responsible for the following tasks:
+
+#. Distinguishing between a cold boot and a warm boot.
+
+#. In the case of a cold boot and the CPU being a secondary CPU, ensuring that
+ the CPU is placed in a platform-specific state until the primary CPU
+ performs the necessary steps to remove it from this state.
+
+#. In the case of a warm boot, ensuring that the CPU jumps to a platform-
+ specific address in the BL31 image in the same processor mode as it was
+ when released from reset.
+
+The following functions need to be implemented by the platform port to enable
+reset vector code to perform the above tasks.
+
+Function : plat_get_my_entrypoint() [mandatory when PROGRAMMABLE_RESET_ADDRESS == 0]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : uintptr_t
+
+This function is called with the MMU and caches disabled
+(``SCTLR_EL3.M`` = 0 and ``SCTLR_EL3.C`` = 0). The function is responsible for
+distinguishing between a warm and cold reset for the current CPU using
+platform-specific means. If it's a warm reset, then it returns the warm
+reset entrypoint point provided to ``plat_setup_psci_ops()`` during
+BL31 initialization. If it's a cold reset then this function must return zero.
+
+This function does not follow the Procedure Call Standard used by the
+Application Binary Interface for the Arm 64-bit architecture. The caller should
+not assume that callee saved registers are preserved across a call to this
+function.
+
+This function fulfills requirement 1 and 3 listed above.
+
+Note that for platforms that support programming the reset address, it is
+expected that a CPU will start executing code directly at the right address,
+both on a cold and warm reset. In this case, there is no need to identify the
+type of reset nor to query the warm reset entrypoint. Therefore, implementing
+this function is not required on such platforms.
+
+Function : plat_secondary_cold_boot_setup() [mandatory when COLD_BOOT_SINGLE_CPU == 0]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+
+This function is called with the MMU and data caches disabled. It is responsible
+for placing the executing secondary CPU in a platform-specific state until the
+primary CPU performs the necessary actions to bring it out of that state and
+allow entry into the OS. This function must not return.
+
+In the Arm FVP port, when using the normal boot flow, each secondary CPU powers
+itself off. The primary CPU is responsible for powering up the secondary CPUs
+when normal world software requires them. When booting an EL3 payload instead,
+they stay powered on and are put in a holding pen until their mailbox gets
+populated.
+
+This function fulfills requirement 2 above.
+
+Note that for platforms that can't release secondary CPUs out of reset, only the
+primary CPU will execute the cold boot code. Therefore, implementing this
+function is not required on such platforms.
+
+Function : plat_is_my_cpu_primary() [mandatory when COLD_BOOT_SINGLE_CPU == 0]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : unsigned int
+
+This function identifies whether the current CPU is the primary CPU or a
+secondary CPU. A return value of zero indicates that the CPU is not the
+primary CPU, while a non-zero return value indicates that the CPU is the
+primary CPU.
+
+Note that for platforms that can't release secondary CPUs out of reset, only the
+primary CPU will execute the cold boot code. Therefore, there is no need to
+distinguish between primary and secondary CPUs and implementing this function is
+not required.
+
+Function : platform_mem_init() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function is called before any access to data is made by the firmware, in
+order to carry out any essential memory initialization.
+
+Function: plat_get_rotpk_info()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void *, void **, unsigned int *, unsigned int *
+ Return : int
+
+This function is mandatory when Trusted Board Boot is enabled. It returns a
+pointer to the ROTPK stored in the platform (or a hash of it) and its length.
+The ROTPK must be encoded in DER format according to the following ASN.1
+structure:
+
+::
+
+ AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY algorithm OPTIONAL
+ }
+
+ SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ subjectPublicKey BIT STRING
+ }
+
+In case the function returns a hash of the key:
+
+::
+
+ DigestInfo ::= SEQUENCE {
+ digestAlgorithm AlgorithmIdentifier,
+ digest OCTET STRING
+ }
+
+The function returns 0 on success. Any other value is treated as error by the
+Trusted Board Boot. The function also reports extra information related
+to the ROTPK in the flags parameter:
+
+::
+
+ ROTPK_IS_HASH : Indicates that the ROTPK returned by the platform is a
+ hash.
+ ROTPK_NOT_DEPLOYED : This allows the platform to skip certificate ROTPK
+ verification while the platform ROTPK is not deployed.
+ When this flag is set, the function does not need to
+ return a platform ROTPK, and the authentication
+ framework uses the ROTPK in the certificate without
+ verifying it against the platform value. This flag
+ must not be used in a deployed production environment.
+
+Function: plat_get_nv_ctr()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void *, unsigned int *
+ Return : int
+
+This function is mandatory when Trusted Board Boot is enabled. It returns the
+non-volatile counter value stored in the platform in the second argument. The
+cookie in the first argument may be used to select the counter in case the
+platform provides more than one (for example, on platforms that use the default
+TBBR CoT, the cookie will correspond to the OID values defined in
+TRUSTED_FW_NVCOUNTER_OID or NON_TRUSTED_FW_NVCOUNTER_OID).
+
+The function returns 0 on success. Any other value means the counter value could
+not be retrieved from the platform.
+
+Function: plat_set_nv_ctr()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void *, unsigned int
+ Return : int
+
+This function is mandatory when Trusted Board Boot is enabled. It sets a new
+counter value in the platform. The cookie in the first argument may be used to
+select the counter (as explained in plat_get_nv_ctr()). The second argument is
+the updated counter value to be written to the NV counter.
+
+The function returns 0 on success. Any other value means the counter value could
+not be updated.
+
+Function: plat_set_nv_ctr2()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void *, const auth_img_desc_t *, unsigned int
+ Return : int
+
+This function is optional when Trusted Board Boot is enabled. If this
+interface is defined, then ``plat_set_nv_ctr()`` need not be defined. The
+first argument passed is a cookie and is typically used to
+differentiate between a Non Trusted NV Counter and a Trusted NV
+Counter. The second argument is a pointer to an authentication image
+descriptor and may be used to decide if the counter is allowed to be
+updated or not. The third argument is the updated counter value to
+be written to the NV counter.
+
+The function returns 0 on success. Any other value means the counter value
+either could not be updated or the authentication image descriptor indicates
+that it is not allowed to be updated.
+
+Common mandatory function modifications
+---------------------------------------
+
+The following functions are mandatory functions which need to be implemented
+by the platform port.
+
+Function : plat_my_core_pos()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : unsigned int
+
+This function returns the index of the calling CPU which is used as a
+CPU-specific linear index into blocks of memory (for example while allocating
+per-CPU stacks). This function will be invoked very early in the
+initialization sequence which mandates that this function should be
+implemented in assembly and should not rely on the availability of a C
+runtime environment. This function can clobber x0 - x8 and must preserve
+x9 - x29.
+
+This function plays a crucial role in the power domain topology framework in
+PSCI and details of this can be found in `Power Domain Topology Design`_.
+
+Function : plat_core_pos_by_mpidr()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : u_register_t
+ Return : int
+
+This function validates the ``MPIDR`` of a CPU and converts it to an index,
+which can be used as a CPU-specific linear index into blocks of memory. In
+case the ``MPIDR`` is invalid, this function returns -1. This function will only
+be invoked by BL31 after the power domain topology is initialized and can
+utilize the C runtime environment. For further details about how TF-A
+represents the power domain topology and how this relates to the linear CPU
+index, please refer `Power Domain Topology Design`_.
+
+Function : plat_get_mbedtls_heap() [when TRUSTED_BOARD_BOOT == 1]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Arguments : void **heap_addr, size_t *heap_size
+ Return : int
+
+This function is invoked during Mbed TLS library initialisation to get a heap,
+by means of a starting address and a size. This heap will then be used
+internally by the Mbed TLS library. Hence, each BL stage that utilises Mbed TLS
+must be able to provide a heap to it.
+
+A helper function can be found in `drivers/auth/mbedtls/mbedtls_common.c` in
+which a heap is statically reserved during compile time inside every image
+(i.e. every BL stage) that utilises Mbed TLS. In this default implementation,
+the function simply returns the address and size of this "pre-allocated" heap.
+For a platform to use this default implementation, only a call to the helper
+from inside plat_get_mbedtls_heap() body is enough and nothing else is needed.
+
+However, by writting their own implementation, platforms have the potential to
+optimise memory usage. For example, on some Arm platforms, the Mbed TLS heap is
+shared between BL1 and BL2 stages and, thus, the necessary space is not reserved
+twice.
+
+On success the function should return 0 and a negative error code otherwise.
+
+Common optional modifications
+-----------------------------
+
+The following are helper functions implemented by the firmware that perform
+common platform-specific tasks. A platform may choose to override these
+definitions.
+
+Function : plat_set_my_stack()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function sets the current stack pointer to the normal memory stack that
+has been allocated for the current CPU. For BL images that only require a
+stack for the primary CPU, the UP version of the function is used. The size
+of the stack allocated to each CPU is specified by the platform defined
+constant ``PLATFORM_STACK_SIZE``.
+
+Common implementations of this function for the UP and MP BL images are
+provided in `plat/common/aarch64/platform_up_stack.S`_ and
+`plat/common/aarch64/platform_mp_stack.S`_
+
+Function : plat_get_my_stack()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : uintptr_t
+
+This function returns the base address of the normal memory stack that
+has been allocated for the current CPU. For BL images that only require a
+stack for the primary CPU, the UP version of the function is used. The size
+of the stack allocated to each CPU is specified by the platform defined
+constant ``PLATFORM_STACK_SIZE``.
+
+Common implementations of this function for the UP and MP BL images are
+provided in `plat/common/aarch64/platform_up_stack.S`_ and
+`plat/common/aarch64/platform_mp_stack.S`_
+
+Function : plat_report_exception()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : void
+
+A platform may need to report various information about its status when an
+exception is taken, for example the current exception level, the CPU security
+state (secure/non-secure), the exception type, and so on. This function is
+called in the following circumstances:
+
+- In BL1, whenever an exception is taken.
+- In BL2, whenever an exception is taken.
+
+The default implementation doesn't do anything, to avoid making assumptions
+about the way the platform displays its status information.
+
+For AArch64, this function receives the exception type as its argument.
+Possible values for exceptions types are listed in the
+`include/common/bl_common.h`_ header file. Note that these constants are not
+related to any architectural exception code; they are just a TF-A convention.
+
+For AArch32, this function receives the exception mode as its argument.
+Possible values for exception modes are listed in the
+`include/lib/aarch32/arch.h`_ header file.
+
+Function : plat_reset_handler()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+A platform may need to do additional initialization after reset. This function
+allows the platform to do the platform specific intializations. Platform
+specific errata workarounds could also be implemented here. The API should
+preserve the values of callee saved registers x19 to x29.
+
+The default implementation doesn't do anything. If a platform needs to override
+the default implementation, refer to the `Firmware Design`_ for general
+guidelines.
+
+Function : plat_disable_acp()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This API allows a platform to disable the Accelerator Coherency Port (if
+present) during a cluster power down sequence. The default weak implementation
+doesn't do anything. Since this API is called during the power down sequence,
+it has restrictions for stack usage and it can use the registers x0 - x17 as
+scratch registers. It should preserve the value in x18 register as it is used
+by the caller to store the return address.
+
+Function : plat_error_handler()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Return : void
+
+This API is called when the generic code encounters an error situation from
+which it cannot continue. It allows the platform to perform error reporting or
+recovery actions (for example, reset the system). This function must not return.
+
+The parameter indicates the type of error using standard codes from ``errno.h``.
+Possible errors reported by the generic code are:
+
+- ``-EAUTH``: a certificate or image could not be authenticated (when Trusted
+ Board Boot is enabled)
+- ``-ENOENT``: the requested image or certificate could not be found or an IO
+ error was detected
+- ``-ENOMEM``: resources exhausted. TF-A does not use dynamic memory, so this
+ error is usually an indication of an incorrect array size
+
+The default implementation simply spins.
+
+Function : plat_panic_handler()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This API is called when the generic code encounters an unexpected error
+situation from which it cannot recover. This function must not return,
+and must be implemented in assembly because it may be called before the C
+environment is initialized.
+
+Note: The address from where it was called is stored in x30 (Link Register).
+The default implementation simply spins.
+
+Function : plat_get_bl_image_load_info()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : bl_load_info_t *
+
+This function returns pointer to the list of images that the platform has
+populated to load. This function is invoked in BL2 to load the
+BL3xx images.
+
+Function : plat_get_next_bl_params()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : bl_params_t *
+
+This function returns a pointer to the shared memory that the platform has
+kept aside to pass TF-A related information that next BL image needs. This
+function is invoked in BL2 to pass this information to the next BL
+image.
+
+Function : plat_get_stack_protector_canary()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : u_register_t
+
+This function returns a random value that is used to initialize the canary used
+when the stack protector is enabled with ENABLE_STACK_PROTECTOR. A predictable
+value will weaken the protection as the attacker could easily write the right
+value as part of the attack most of the time. Therefore, it should return a
+true random number.
+
+Note: For the protection to be effective, the global data need to be placed at
+a lower address than the stack bases. Failure to do so would allow an attacker
+to overwrite the canary as part of the stack buffer overflow attack.
+
+Function : plat_flush_next_bl_params()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function flushes to main memory all the image params that are passed to
+next image. This function is invoked in BL2 to flush this information
+to the next BL image.
+
+Function : plat_log_get_prefix()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : const char *
+
+This function defines the prefix string corresponding to the `log_level` to be
+prepended to all the log output from TF-A. The `log_level` (argument) will
+correspond to one of the standard log levels defined in debug.h. The platform
+can override the common implementation to define a different prefix string for
+the log output. The implementation should be robust to future changes that
+increase the number of log levels.
+
+Modifications specific to a Boot Loader stage
+---------------------------------------------
+
+Boot Loader Stage 1 (BL1)
+-------------------------
+
+BL1 implements the reset vector where execution starts from after a cold or
+warm boot. For each CPU, BL1 is responsible for the following tasks:
+
+#. Handling the reset as described in section 2.2
+
+#. In the case of a cold boot and the CPU being the primary CPU, ensuring that
+ only this CPU executes the remaining BL1 code, including loading and passing
+ control to the BL2 stage.
+
+#. Identifying and starting the Firmware Update process (if required).
+
+#. Loading the BL2 image from non-volatile storage into secure memory at the
+ address specified by the platform defined constant ``BL2_BASE``.
+
+#. Populating a ``meminfo`` structure with the following information in memory,
+ accessible by BL2 immediately upon entry.
+
+ ::
+
+ meminfo.total_base = Base address of secure RAM visible to BL2
+ meminfo.total_size = Size of secure RAM visible to BL2
+
+ By default, BL1 places this ``meminfo`` structure at the end of secure
+ memory visible to BL2.
+
+ It is possible for the platform to decide where it wants to place the
+ ``meminfo`` structure for BL2 or restrict the amount of memory visible to
+ BL2 by overriding the weak default implementation of
+ ``bl1_plat_handle_post_image_load`` API.
+
+The following functions need to be implemented by the platform port to enable
+BL1 to perform the above tasks.
+
+Function : bl1_early_platform_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU.
+
+On Arm standard platforms, this function:
+
+- Enables a secure instance of SP805 to act as the Trusted Watchdog.
+
+- Initializes a UART (PL011 console), which enables access to the ``printf``
+ family of functions in BL1.
+
+- Enables issuing of snoop and DVM (Distributed Virtual Memory) requests to
+ the CCI slave interface corresponding to the cluster that includes the
+ primary CPU.
+
+Function : bl1_plat_arch_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function performs any platform-specific and architectural setup that the
+platform requires. Platform-specific setup might include configuration of
+memory controllers and the interconnect.
+
+In Arm standard platforms, this function enables the MMU.
+
+This function helps fulfill requirement 2 above.
+
+Function : bl1_platform_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches enabled. It is responsible
+for performing any remaining platform-specific setup that can occur after the
+MMU and data cache have been enabled.
+
+if support for multiple boot sources is required, it initializes the boot
+sequence used by plat_try_next_boot_source().
+
+In Arm standard platforms, this function initializes the storage abstraction
+layer used to load the next bootloader image.
+
+This function helps fulfill requirement 4 above.
+
+Function : bl1_plat_sec_mem_layout() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : meminfo *
+
+This function should only be called on the cold boot path. It executes with the
+MMU and data caches enabled. The pointer returned by this function must point to
+a ``meminfo`` structure containing the extents and availability of secure RAM for
+the BL1 stage.
+
+::
+
+ meminfo.total_base = Base address of secure RAM visible to BL1
+ meminfo.total_size = Size of secure RAM visible to BL1
+
+This information is used by BL1 to load the BL2 image in secure RAM. BL1 also
+populates a similar structure to tell BL2 the extents of memory available for
+its own use.
+
+This function helps fulfill requirements 4 and 5 above.
+
+Function : bl1_plat_prepare_exit() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : entry_point_info_t *
+ Return : void
+
+This function is called prior to exiting BL1 in response to the
+``BL1_SMC_RUN_IMAGE`` SMC request raised by BL2. It should be used to perform
+platform specific clean up or bookkeeping operations before transferring
+control to the next image. It receives the address of the ``entry_point_info_t``
+structure passed from BL2. This function runs with MMU disabled.
+
+Function : bl1_plat_set_ep_info() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int image_id, entry_point_info_t *ep_info
+ Return : void
+
+This function allows platforms to override ``ep_info`` for the given ``image_id``.
+
+The default implementation just returns.
+
+Function : bl1_plat_get_next_image_id() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : unsigned int
+
+This and the following function must be overridden to enable the FWU feature.
+
+BL1 calls this function after platform setup to identify the next image to be
+loaded and executed. If the platform returns ``BL2_IMAGE_ID`` then BL1 proceeds
+with the normal boot sequence, which loads and executes BL2. If the platform
+returns a different image id, BL1 assumes that Firmware Update is required.
+
+The default implementation always returns ``BL2_IMAGE_ID``. The Arm development
+platforms override this function to detect if firmware update is required, and
+if so, return the first image in the firmware update process.
+
+Function : bl1_plat_get_image_desc() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int image_id
+ Return : image_desc_t *
+
+BL1 calls this function to get the image descriptor information ``image_desc_t``
+for the provided ``image_id`` from the platform.
+
+The default implementation always returns a common BL2 image descriptor. Arm
+standard platforms return an image descriptor corresponding to BL2 or one of
+the firmware update images defined in the Trusted Board Boot Requirements
+specification.
+
+Function : bl1_plat_handle_pre_image_load() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int image_id
+ Return : int
+
+This function can be used by the platforms to update/use image information
+corresponding to ``image_id``. This function is invoked in BL1, both in cold
+boot and FWU code path, before loading the image.
+
+Function : bl1_plat_handle_post_image_load() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int image_id
+ Return : int
+
+This function can be used by the platforms to update/use image information
+corresponding to ``image_id``. This function is invoked in BL1, both in cold
+boot and FWU code path, after loading and authenticating the image.
+
+The default weak implementation of this function calculates the amount of
+Trusted SRAM that can be used by BL2 and allocates a ``meminfo_t``
+structure at the beginning of this free memory and populates it. The address
+of ``meminfo_t`` structure is updated in ``arg1`` of the entrypoint
+information to BL2.
+
+Function : bl1_plat_fwu_done() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int image_id, uintptr_t image_src,
+ unsigned int image_size
+ Return : void
+
+BL1 calls this function when the FWU process is complete. It must not return.
+The platform may override this function to take platform specific action, for
+example to initiate the normal boot flow.
+
+The default implementation spins forever.
+
+Function : bl1_plat_mem_check() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uintptr_t mem_base, unsigned int mem_size,
+ unsigned int flags
+ Return : int
+
+BL1 calls this function while handling FWU related SMCs, more specifically when
+copying or authenticating an image. Its responsibility is to ensure that the
+region of memory identified by ``mem_base`` and ``mem_size`` is mapped in BL1, and
+that this memory corresponds to either a secure or non-secure memory region as
+indicated by the security state of the ``flags`` argument.
+
+This function can safely assume that the value resulting from the addition of
+``mem_base`` and ``mem_size`` fits into a ``uintptr_t`` type variable and does not
+overflow.
+
+This function must return 0 on success, a non-null error code otherwise.
+
+The default implementation of this function asserts therefore platforms must
+override it when using the FWU feature.
+
+Boot Loader Stage 2 (BL2)
+-------------------------
+
+The BL2 stage is executed only by the primary CPU, which is determined in BL1
+using the ``platform_is_primary_cpu()`` function. BL1 passed control to BL2 at
+``BL2_BASE``. BL2 executes in Secure EL1 and and invokes
+``plat_get_bl_image_load_info()`` to retrieve the list of images to load from
+non-volatile storage to secure/non-secure RAM. After all the images are loaded
+then BL2 invokes ``plat_get_next_bl_params()`` to get the list of executable
+images to be passed to the next BL image.
+
+The following functions must be implemented by the platform port to enable BL2
+to perform the above tasks.
+
+Function : bl2_early_platform_setup2() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : u_register_t, u_register_t, u_register_t, u_register_t
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU. The 4 arguments are passed by BL1 to BL2 and these arguments
+are platform specific.
+
+On Arm standard platforms, the arguments received are :
+
+ arg0 - Points to load address of HW_CONFIG if present
+
+ arg1 - ``meminfo`` structure populated by BL1. The platform copies
+ the contents of ``meminfo`` as it may be subsequently overwritten by BL2.
+
+On Arm standard platforms, this function also:
+
+- Initializes a UART (PL011 console), which enables access to the ``printf``
+ family of functions in BL2.
+
+- Initializes the storage abstraction layer used to load further bootloader
+ images. It is necessary to do this early on platforms with a SCP_BL2 image,
+ since the later ``bl2_platform_setup`` must be done after SCP_BL2 is loaded.
+
+Function : bl2_plat_arch_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU.
+
+The purpose of this function is to perform any architectural initialization
+that varies across platforms.
+
+On Arm standard platforms, this function enables the MMU.
+
+Function : bl2_platform_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initialization in ``bl2_plat_arch_setup()``. It is only
+called by the primary CPU.
+
+The purpose of this function is to perform any platform initialization
+specific to BL2.
+
+In Arm standard platforms, this function performs security setup, including
+configuration of the TrustZone controller to allow non-secure masters access
+to most of DRAM. Part of DRAM is reserved for secure world use.
+
+Function : bl2_plat_handle_pre_image_load() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : int
+
+This function can be used by the platforms to update/use image information
+for given ``image_id``. This function is currently invoked in BL2 before
+loading each image.
+
+Function : bl2_plat_handle_post_image_load() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int
+ Return : int
+
+This function can be used by the platforms to update/use image information
+for given ``image_id``. This function is currently invoked in BL2 after
+loading each image.
+
+Function : bl2_plat_preload_setup [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This optional function performs any BL2 platform initialization
+required before image loading, that is not done later in
+bl2_platform_setup(). Specifically, if support for multiple
+boot sources is required, it initializes the boot sequence used by
+plat_try_next_boot_source().
+
+Function : plat_try_next_boot_source() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : int
+
+This optional function passes to the next boot source in the redundancy
+sequence.
+
+This function moves the current boot redundancy source to the next
+element in the boot sequence. If there are no more boot sources then it
+must return 0, otherwise it must return 1. The default implementation
+of this always returns 0.
+
+Boot Loader Stage 2 (BL2) at EL3
+--------------------------------
+
+When the platform has a non-TF-A Boot ROM it is desirable to jump
+directly to BL2 instead of TF-A BL1. In this case BL2 is expected to
+execute at EL3 instead of executing at EL1. Refer to the `Firmware
+Design`_ for more information.
+
+All mandatory functions of BL2 must be implemented, except the functions
+bl2_early_platform_setup and bl2_el3_plat_arch_setup, because
+their work is done now by bl2_el3_early_platform_setup and
+bl2_el3_plat_arch_setup. These functions should generally implement
+the bl1_plat_xxx() and bl2_plat_xxx() functionality combined.
+
+
+Function : bl2_el3_early_platform_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : u_register_t, u_register_t, u_register_t, u_register_t
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU. This function receives four parameters which can be used
+by the platform to pass any needed information from the Boot ROM to BL2.
+
+On Arm standard platforms, this function does the following:
+
+- Initializes a UART (PL011 console), which enables access to the ``printf``
+ family of functions in BL2.
+
+- Initializes the storage abstraction layer used to load further bootloader
+ images. It is necessary to do this early on platforms with a SCP_BL2 image,
+ since the later ``bl2_platform_setup`` must be done after SCP_BL2 is loaded.
+
+- Initializes the private variables that define the memory layout used.
+
+Function : bl2_el3_plat_arch_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU.
+
+The purpose of this function is to perform any architectural initialization
+that varies across platforms.
+
+On Arm standard platforms, this function enables the MMU.
+
+Function : bl2_el3_plat_prepare_exit() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function is called prior to exiting BL2 and run the next image.
+It should be used to perform platform specific clean up or bookkeeping
+operations before transferring control to the next image. This function
+runs with MMU disabled.
+
+FWU Boot Loader Stage 2 (BL2U)
+------------------------------
+
+The AP Firmware Updater Configuration, BL2U, is an optional part of the FWU
+process and is executed only by the primary CPU. BL1 passes control to BL2U at
+``BL2U_BASE``. BL2U executes in Secure-EL1 and is responsible for:
+
+#. (Optional) Transferring the optional SCP_BL2U binary image from AP secure
+ memory to SCP RAM. BL2U uses the SCP_BL2U ``image_info`` passed by BL1.
+ ``SCP_BL2U_BASE`` defines the address in AP secure memory where SCP_BL2U
+ should be copied from. Subsequent handling of the SCP_BL2U image is
+ implemented by the platform specific ``bl2u_plat_handle_scp_bl2u()`` function.
+ If ``SCP_BL2U_BASE`` is not defined then this step is not performed.
+
+#. Any platform specific setup required to perform the FWU process. For
+ example, Arm standard platforms initialize the TZC controller so that the
+ normal world can access DDR memory.
+
+The following functions must be implemented by the platform port to enable
+BL2U to perform the tasks mentioned above.
+
+Function : bl2u_early_platform_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : meminfo *mem_info, void *plat_info
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only
+called by the primary CPU. The arguments to this function is the address
+of the ``meminfo`` structure and platform specific info provided by BL1.
+
+The platform may copy the contents of the ``mem_info`` and ``plat_info`` into
+private storage as the original memory may be subsequently overwritten by BL2U.
+
+On Arm CSS platforms ``plat_info`` is interpreted as an ``image_info_t`` structure,
+to extract SCP_BL2U image information, which is then copied into a private
+variable.
+
+Function : bl2u_plat_arch_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only
+called by the primary CPU.
+
+The purpose of this function is to perform any architectural initialization
+that varies across platforms, for example enabling the MMU (since the memory
+map differs across platforms).
+
+Function : bl2u_platform_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initialization in ``bl2u_plat_arch_setup()``. It is only
+called by the primary CPU.
+
+The purpose of this function is to perform any platform initialization
+specific to BL2U.
+
+In Arm standard platforms, this function performs security setup, including
+configuration of the TrustZone controller to allow non-secure masters access
+to most of DRAM. Part of DRAM is reserved for secure world use.
+
+Function : bl2u_plat_handle_scp_bl2u() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : int
+
+This function is used to perform any platform-specific actions required to
+handle the SCP firmware. Typically it transfers the image into SCP memory using
+a platform-specific protocol and waits until SCP executes it and signals to the
+Application Processor (AP) for BL2U execution to continue.
+
+This function returns 0 on success, a negative error code otherwise.
+This function is included if SCP_BL2U_BASE is defined.
+
+Boot Loader Stage 3-1 (BL31)
+----------------------------
+
+During cold boot, the BL31 stage is executed only by the primary CPU. This is
+determined in BL1 using the ``platform_is_primary_cpu()`` function. BL1 passes
+control to BL31 at ``BL31_BASE``. During warm boot, BL31 is executed by all
+CPUs. BL31 executes at EL3 and is responsible for:
+
+#. Re-initializing all architectural and platform state. Although BL1 performs
+ some of this initialization, BL31 remains resident in EL3 and must ensure
+ that EL3 architectural and platform state is completely initialized. It
+ should make no assumptions about the system state when it receives control.
+
+#. Passing control to a normal world BL image, pre-loaded at a platform-
+ specific address by BL2. On ARM platforms, BL31 uses the ``bl_params`` list
+ populated by BL2 in memory to do this.
+
+#. Providing runtime firmware services. Currently, BL31 only implements a
+ subset of the Power State Coordination Interface (PSCI) API as a runtime
+ service. See Section 3.3 below for details of porting the PSCI
+ implementation.
+
+#. Optionally passing control to the BL32 image, pre-loaded at a platform-
+ specific address by BL2. BL31 exports a set of APIs that allow runtime
+ services to specify the security state in which the next image should be
+ executed and run the corresponding image. On ARM platforms, BL31 uses the
+ ``bl_params`` list populated by BL2 in memory to do this.
+
+If BL31 is a reset vector, It also needs to handle the reset as specified in
+section 2.2 before the tasks described above.
+
+The following functions must be implemented by the platform port to enable BL31
+to perform the above tasks.
+
+Function : bl31_early_platform_setup2() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : u_register_t, u_register_t, u_register_t, u_register_t
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU. BL2 can pass 4 arguments to BL31 and these arguments are
+platform specific.
+
+In Arm standard platforms, the arguments received are :
+
+ arg0 - The pointer to the head of `bl_params_t` list
+ which is list of executable images following BL31,
+
+ arg1 - Points to load address of SOC_FW_CONFIG if present
+
+ arg2 - Points to load address of HW_CONFIG if present
+
+ arg3 - A special value to verify platform parameters from BL2 to BL31. Not
+ used in release builds.
+
+The function runs through the `bl_param_t` list and extracts the entry point
+information for BL32 and BL33. It also performs the following:
+
+- Initialize a UART (PL011 console), which enables access to the ``printf``
+ family of functions in BL31.
+
+- Enable issuing of snoop and DVM (Distributed Virtual Memory) requests to the
+ CCI slave interface corresponding to the cluster that includes the primary
+ CPU.
+
+Function : bl31_plat_arch_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function executes with the MMU and data caches disabled. It is only called
+by the primary CPU.
+
+The purpose of this function is to perform any architectural initialization
+that varies across platforms.
+
+On Arm standard platforms, this function enables the MMU.
+
+Function : bl31_platform_setup() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initialization in ``bl31_plat_arch_setup()``. It is only
+called by the primary CPU.
+
+The purpose of this function is to complete platform initialization so that both
+BL31 runtime services and normal world software can function correctly.
+
+On Arm standard platforms, this function does the following:
+
+- Initialize the generic interrupt controller.
+
+ Depending on the GIC driver selected by the platform, the appropriate GICv2
+ or GICv3 initialization will be done, which mainly consists of:
+
+ - Enable secure interrupts in the GIC CPU interface.
+ - Disable the legacy interrupt bypass mechanism.
+ - Configure the priority mask register to allow interrupts of all priorities
+ to be signaled to the CPU interface.
+ - Mark SGIs 8-15 and the other secure interrupts on the platform as secure.
+ - Target all secure SPIs to CPU0.
+ - Enable these secure interrupts in the GIC distributor.
+ - Configure all other interrupts as non-secure.
+ - Enable signaling of secure interrupts in the GIC distributor.
+
+- Enable system-level implementation of the generic timer counter through the
+ memory mapped interface.
+
+- Grant access to the system counter timer module
+
+- Initialize the power controller device.
+
+ In particular, initialise the locks that prevent concurrent accesses to the
+ power controller device.
+
+Function : bl31_plat_runtime_setup() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+The purpose of this function is allow the platform to perform any BL31 runtime
+setup just prior to BL31 exit during cold boot. The default weak
+implementation of this function will invoke ``console_switch_state()`` to switch
+console output to consoles marked for use in the ``runtime`` state.
+
+Function : bl31_plat_get_next_image_ep_info() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uint32_t
+ Return : entry_point_info *
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initializations in ``bl31_plat_arch_setup()``.
+
+This function is called by ``bl31_main()`` to retrieve information provided by
+BL2 for the next image in the security state specified by the argument. BL31
+uses this information to pass control to that image in the specified security
+state. This function must return a pointer to the ``entry_point_info`` structure
+(that was copied during ``bl31_early_platform_setup()``) if the image exists. It
+should return NULL otherwise.
+
+Function : bl31_plat_enable_mmu [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uint32_t
+ Return : void
+
+This function enables the MMU. The boot code calls this function with MMU and
+caches disabled. This function should program necessary registers to enable
+translation, and upon return, the MMU on the calling PE must be enabled.
+
+The function must honor flags passed in the first argument. These flags are
+defined by the translation library, and can be found in the file
+``include/lib/xlat_tables/xlat_mmu_helpers.h``.
+
+On DynamIQ systems, this function must not use stack while enabling MMU, which
+is how the function in xlat table library version 2 is implemented.
+
+Function : plat_init_apiakey [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : uint64_t *
+
+This function populates the ``plat_apiakey`` array that contains the values used
+to set the ``APIAKey{Hi,Lo}_EL1`` registers. It returns a pointer to this array.
+
+The value should be obtained from a reliable source of randomness.
+
+This function is only needed if ARMv8.3 pointer authentication is used in the
+Trusted Firmware by building with ``ENABLE_PAUTH=1``.
+
+Function : plat_get_syscnt_freq2() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : unsigned int
+
+This function is used by the architecture setup code to retrieve the counter
+frequency for the CPU's generic timer. This value will be programmed into the
+``CNTFRQ_EL0`` register. In Arm standard platforms, it returns the base frequency
+of the system counter, which is retrieved from the first entry in the frequency
+modes table.
+
+#define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When ``USE_COHERENT_MEM = 0``, this constant defines the total memory (in
+bytes) aligned to the cache line boundary that should be allocated per-cpu to
+accommodate all the bakery locks.
+
+If this constant is not defined when ``USE_COHERENT_MEM = 0``, the linker
+calculates the size of the ``bakery_lock`` input section, aligns it to the
+nearest ``CACHE_WRITEBACK_GRANULE``, multiplies it with ``PLATFORM_CORE_COUNT``
+and stores the result in a linker symbol. This constant prevents a platform
+from relying on the linker and provide a more efficient mechanism for
+accessing per-cpu bakery lock information.
+
+If this constant is defined and its value is not equal to the value
+calculated by the linker then a link time assertion is raised. A compile time
+assertion is raised if the value of the constant is not aligned to the cache
+line boundary.
+
+SDEI porting requirements
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The SDEI dispatcher requires the platform to provide the following macros
+and functions, of which some are optional, and some others mandatory.
+
+Macros
+......
+
+Macro: PLAT_SDEI_NORMAL_PRI [mandatory]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This macro must be defined to the EL3 exception priority level associated with
+Normal SDEI events on the platform. This must have a higher value (therefore of
+lower priority) than ``PLAT_SDEI_CRITICAL_PRI``.
+
+Macro: PLAT_SDEI_CRITICAL_PRI [mandatory]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This macro must be defined to the EL3 exception priority level associated with
+Critical SDEI events on the platform. This must have a lower value (therefore of
+higher priority) than ``PLAT_SDEI_NORMAL_PRI``.
+
+**Note**: SDEI exception priorities must be the lowest among Secure priorities.
+Among the SDEI exceptions, Critical SDEI priority must be higher than Normal
+SDEI priority.
+
+Functions
+.........
+
+Function: int plat_sdei_validate_entry_point(uintptr_t ep) [optional]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ Argument: uintptr_t
+ Return: int
+
+This function validates the address of client entry points provided for both
+event registration and *Complete and Resume* SDEI calls. The function takes one
+argument, which is the address of the handler the SDEI client requested to
+register. The function must return ``0`` for successful validation, or ``-1``
+upon failure.
+
+The default implementation always returns ``0``. On Arm platforms, this function
+is implemented to translate the entry point to physical address, and further to
+ensure that the address is located in Non-secure DRAM.
+
+Function: void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr) [optional]
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+::
+
+ Argument: uint64_t
+ Argument: unsigned int
+ Return: void
+
+SDEI specification requires that a PE comes out of reset with the events masked.
+The client therefore is expected to call ``PE_UNMASK`` to unmask SDEI events on
+the PE. No SDEI events can be dispatched until such time.
+
+Should a PE receive an interrupt that was bound to an SDEI event while the
+events are masked on the PE, the dispatcher implementation invokes the function
+``plat_sdei_handle_masked_trigger``. The MPIDR of the PE that received the
+interrupt and the interrupt ID are passed as parameters.
+
+The default implementation only prints out a warning message.
+
+Power State Coordination Interface (in BL31)
+--------------------------------------------
+
+The TF-A implementation of the PSCI API is based around the concept of a
+*power domain*. A *power domain* is a CPU or a logical group of CPUs which
+share some state on which power management operations can be performed as
+specified by `PSCI`_. Each CPU in the system is assigned a cpu index which is
+a unique number between ``0`` and ``PLATFORM_CORE_COUNT - 1``. The
+*power domains* are arranged in a hierarchical tree structure and each
+*power domain* can be identified in a system by the cpu index of any CPU that
+is part of that domain and a *power domain level*. A processing element (for
+example, a CPU) is at level 0. If the *power domain* node above a CPU is a
+logical grouping of CPUs that share some state, then level 1 is that group of
+CPUs (for example, a cluster), and level 2 is a group of clusters (for
+example, the system). More details on the power domain topology and its
+organization can be found in `Power Domain Topology Design`_.
+
+BL31's platform initialization code exports a pointer to the platform-specific
+power management operations required for the PSCI implementation to function
+correctly. This information is populated in the ``plat_psci_ops`` structure. The
+PSCI implementation calls members of the ``plat_psci_ops`` structure for performing
+power management operations on the power domains. For example, the target
+CPU is specified by its ``MPIDR`` in a PSCI ``CPU_ON`` call. The ``pwr_domain_on()``
+handler (if present) is called for the CPU power domain.
+
+The ``power-state`` parameter of a PSCI ``CPU_SUSPEND`` call can be used to
+describe composite power states specific to a platform. The PSCI implementation
+defines a generic representation of the power-state parameter, which is an
+array of local power states where each index corresponds to a power domain
+level. Each entry contains the local power state the power domain at that power
+level could enter. It depends on the ``validate_power_state()`` handler to
+convert the power-state parameter (possibly encoding a composite power state)
+passed in a PSCI ``CPU_SUSPEND`` call to this representation.
+
+The following functions form part of platform port of PSCI functionality.
+
+Function : plat_psci_stat_accounting_start() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : const psci_power_state_t *
+ Return : void
+
+This is an optional hook that platforms can implement for residency statistics
+accounting before entering a low power state. The ``pwr_domain_state`` field of
+``state_info`` (first argument) can be inspected if stat accounting is done
+differently at CPU level versus higher levels. As an example, if the element at
+index 0 (CPU power level) in the ``pwr_domain_state`` array indicates a power down
+state, special hardware logic may be programmed in order to keep track of the
+residency statistics. For higher levels (array indices > 0), the residency
+statistics could be tracked in software using PMF. If ``ENABLE_PMF`` is set, the
+default implementation will use PMF to capture timestamps.
+
+Function : plat_psci_stat_accounting_stop() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : const psci_power_state_t *
+ Return : void
+
+This is an optional hook that platforms can implement for residency statistics
+accounting after exiting from a low power state. The ``pwr_domain_state`` field
+of ``state_info`` (first argument) can be inspected if stat accounting is done
+differently at CPU level versus higher levels. As an example, if the element at
+index 0 (CPU power level) in the ``pwr_domain_state`` array indicates a power down
+state, special hardware logic may be programmed in order to keep track of the
+residency statistics. For higher levels (array indices > 0), the residency
+statistics could be tracked in software using PMF. If ``ENABLE_PMF`` is set, the
+default implementation will use PMF to capture timestamps.
+
+Function : plat_psci_stat_get_residency() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int, const psci_power_state_t *, int
+ Return : u_register_t
+
+This is an optional interface that is is invoked after resuming from a low power
+state and provides the time spent resident in that low power state by the power
+domain at a particular power domain level. When a CPU wakes up from suspend,
+all its parent power domain levels are also woken up. The generic PSCI code
+invokes this function for each parent power domain that is resumed and it
+identified by the ``lvl`` (first argument) parameter. The ``state_info`` (second
+argument) describes the low power state that the power domain has resumed from.
+The current CPU is the first CPU in the power domain to resume from the low
+power state and the ``last_cpu_idx`` (third parameter) is the index of the last
+CPU in the power domain to suspend and may be needed to calculate the residency
+for that power domain.
+
+Function : plat_get_target_pwr_state() [optional]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : unsigned int, const plat_local_state_t *, unsigned int
+ Return : plat_local_state_t
+
+The PSCI generic code uses this function to let the platform participate in
+state coordination during a power management operation. The function is passed
+a pointer to an array of platform specific local power state ``states`` (second
+argument) which contains the requested power state for each CPU at a particular
+power domain level ``lvl`` (first argument) within the power domain. The function
+is expected to traverse this array of upto ``ncpus`` (third argument) and return
+a coordinated target power state by the comparing all the requested power
+states. The target power state should not be deeper than any of the requested
+power states.
+
+A weak definition of this API is provided by default wherein it assumes
+that the platform assigns a local state value in order of increasing depth
+of the power state i.e. for two power states X & Y, if X < Y
+then X represents a shallower power state than Y. As a result, the
+coordinated target local power state for a power domain will be the minimum
+of the requested local power state values.
+
+Function : plat_get_power_domain_tree_desc() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : const unsigned char *
+
+This function returns a pointer to the byte array containing the power domain
+topology tree description. The format and method to construct this array are
+described in `Power Domain Topology Design`_. The BL31 PSCI initialization code
+requires this array to be described by the platform, either statically or
+dynamically, to initialize the power domain topology tree. In case the array
+is populated dynamically, then plat_core_pos_by_mpidr() and
+plat_my_core_pos() should also be implemented suitably so that the topology
+tree description matches the CPU indices returned by these APIs. These APIs
+together form the platform interface for the PSCI topology framework.
+
+Function : plat_setup_psci_ops() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uintptr_t, const plat_psci_ops **
+ Return : int
+
+This function may execute with the MMU and data caches enabled if the platform
+port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only
+called by the primary CPU.
+
+This function is called by PSCI initialization code. Its purpose is to let
+the platform layer know about the warm boot entrypoint through the
+``sec_entrypoint`` (first argument) and to export handler routines for
+platform-specific psci power management actions by populating the passed
+pointer with a pointer to BL31's private ``plat_psci_ops`` structure.
+
+A description of each member of this structure is given below. Please refer to
+the Arm FVP specific implementation of these handlers in
+`plat/arm/board/fvp/fvp_pm.c`_ as an example. For each PSCI function that the
+platform wants to support, the associated operation or operations in this
+structure must be provided and implemented (Refer section 4 of
+`Firmware Design`_ for the PSCI API supported in TF-A). To disable a PSCI
+function in a platform port, the operation should be removed from this
+structure instead of providing an empty implementation.
+
+plat_psci_ops.cpu_standby()
+...........................
+
+Perform the platform-specific actions to enter the standby state for a cpu
+indicated by the passed argument. This provides a fast path for CPU standby
+wherein overheads of PSCI state management and lock acquisition is avoided.
+For this handler to be invoked by the PSCI ``CPU_SUSPEND`` API implementation,
+the suspend state type specified in the ``power-state`` parameter should be
+STANDBY and the target power domain level specified should be the CPU. The
+handler should put the CPU into a low power retention state (usually by
+issuing a wfi instruction) and ensure that it can be woken up from that
+state by a normal interrupt. The generic code expects the handler to succeed.
+
+plat_psci_ops.pwr_domain_on()
+.............................
+
+Perform the platform specific actions to power on a CPU, specified
+by the ``MPIDR`` (first argument). The generic code expects the platform to
+return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure.
+
+plat_psci_ops.pwr_domain_off()
+..............................
+
+Perform the platform specific actions to prepare to power off the calling CPU
+and its higher parent power domain levels as indicated by the ``target_state``
+(first argument). It is called by the PSCI ``CPU_OFF`` API implementation.
+
+The ``target_state`` encodes the platform coordinated target local power states
+for the CPU power domain and its parent power domain levels. The handler
+needs to perform power management operation corresponding to the local state
+at each power level.
+
+For this handler, the local power state for the CPU power domain will be a
+power down state where as it could be either power down, retention or run state
+for the higher power domain levels depending on the result of state
+coordination. The generic code expects the handler to succeed.
+
+plat_psci_ops.pwr_domain_suspend_pwrdown_early() [optional]
+...........................................................
+
+This optional function may be used as a performance optimization to replace
+or complement pwr_domain_suspend() on some platforms. Its calling semantics
+are identical to pwr_domain_suspend(), except the PSCI implementation only
+calls this function when suspending to a power down state, and it guarantees
+that data caches are enabled.
+
+When HW_ASSISTED_COHERENCY = 0, the PSCI implementation disables data caches
+before calling pwr_domain_suspend(). If the target_state corresponds to a
+power down state and it is safe to perform some or all of the platform
+specific actions in that function with data caches enabled, it may be more
+efficient to move those actions to this function. When HW_ASSISTED_COHERENCY
+= 1, data caches remain enabled throughout, and so there is no advantage to
+moving platform specific actions to this function.
+
+plat_psci_ops.pwr_domain_suspend()
+..................................
+
+Perform the platform specific actions to prepare to suspend the calling
+CPU and its higher parent power domain levels as indicated by the
+``target_state`` (first argument). It is called by the PSCI ``CPU_SUSPEND``
+API implementation.
+
+The ``target_state`` has a similar meaning as described in
+the ``pwr_domain_off()`` operation. It encodes the platform coordinated
+target local power states for the CPU power domain and its parent
+power domain levels. The handler needs to perform power management operation
+corresponding to the local state at each power level. The generic code
+expects the handler to succeed.
+
+The difference between turning a power domain off versus suspending it is that
+in the former case, the power domain is expected to re-initialize its state
+when it is next powered on (see ``pwr_domain_on_finish()``). In the latter
+case, the power domain is expected to save enough state so that it can resume
+execution by restoring this state when its powered on (see
+``pwr_domain_suspend_finish()``).
+
+When suspending a core, the platform can also choose to power off the GICv3
+Redistributor and ITS through an implementation-defined sequence. To achieve
+this safely, the ITS context must be saved first. The architectural part is
+implemented by the ``gicv3_its_save_disable()`` helper, but most of the needed
+sequence is implementation defined and it is therefore the responsibility of
+the platform code to implement the necessary sequence. Then the GIC
+Redistributor context can be saved using the ``gicv3_rdistif_save()`` helper.
+Powering off the Redistributor requires the implementation to support it and it
+is the responsibility of the platform code to execute the right implementation
+defined sequence.
+
+When a system suspend is requested, the platform can also make use of the
+``gicv3_distif_save()`` helper to save the context of the GIC Distributor after
+it has saved the context of the Redistributors and ITS of all the cores in the
+system. The context of the Distributor can be large and may require it to be
+allocated in a special area if it cannot fit in the platform's global static
+data, for example in DRAM. The Distributor can then be powered down using an
+implementation-defined sequence.
+
+plat_psci_ops.pwr_domain_pwr_down_wfi()
+.......................................
+
+This is an optional function and, if implemented, is expected to perform
+platform specific actions including the ``wfi`` invocation which allows the
+CPU to powerdown. Since this function is invoked outside the PSCI locks,
+the actions performed in this hook must be local to the CPU or the platform
+must ensure that races between multiple CPUs cannot occur.
+
+The ``target_state`` has a similar meaning as described in the ``pwr_domain_off()``
+operation and it encodes the platform coordinated target local power states for
+the CPU power domain and its parent power domain levels. This function must
+not return back to the caller.
+
+If this function is not implemented by the platform, PSCI generic
+implementation invokes ``psci_power_down_wfi()`` for power down.
+
+plat_psci_ops.pwr_domain_on_finish()
+....................................
+
+This function is called by the PSCI implementation after the calling CPU is
+powered on and released from reset in response to an earlier PSCI ``CPU_ON`` call.
+It performs the platform-specific setup required to initialize enough state for
+this CPU to enter the normal world and also provide secure runtime firmware
+services.
+
+The ``target_state`` (first argument) is the prior state of the power domains
+immediately before the CPU was turned on. It indicates which power domains
+above the CPU might require initialization due to having previously been in
+low power states. The generic code expects the handler to succeed.
+
+plat_psci_ops.pwr_domain_suspend_finish()
+.........................................
+
+This function is called by the PSCI implementation after the calling CPU is
+powered on and released from reset in response to an asynchronous wakeup
+event, for example a timer interrupt that was programmed by the CPU during the
+``CPU_SUSPEND`` call or ``SYSTEM_SUSPEND`` call. It performs the platform-specific
+setup required to restore the saved state for this CPU to resume execution
+in the normal world and also provide secure runtime firmware services.
+
+The ``target_state`` (first argument) has a similar meaning as described in
+the ``pwr_domain_on_finish()`` operation. The generic code expects the platform
+to succeed.
+
+If the Distributor, Redistributors or ITS have been powered off as part of a
+suspend, their context must be restored in this function in the reverse order
+to how they were saved during suspend sequence.
+
+plat_psci_ops.system_off()
+..........................
+
+This function is called by PSCI implementation in response to a ``SYSTEM_OFF``
+call. It performs the platform-specific system poweroff sequence after
+notifying the Secure Payload Dispatcher.
+
+plat_psci_ops.system_reset()
+............................
+
+This function is called by PSCI implementation in response to a ``SYSTEM_RESET``
+call. It performs the platform-specific system reset sequence after
+notifying the Secure Payload Dispatcher.
+
+plat_psci_ops.validate_power_state()
+....................................
+
+This function is called by the PSCI implementation during the ``CPU_SUSPEND``
+call to validate the ``power_state`` parameter of the PSCI API and if valid,
+populate it in ``req_state`` (second argument) array as power domain level
+specific local states. If the ``power_state`` is invalid, the platform must
+return PSCI_E_INVALID_PARAMS as error, which is propagated back to the
+normal world PSCI client.
+
+plat_psci_ops.validate_ns_entrypoint()
+......................................
+
+This function is called by the PSCI implementation during the ``CPU_SUSPEND``,
+``SYSTEM_SUSPEND`` and ``CPU_ON`` calls to validate the non-secure ``entry_point``
+parameter passed by the normal world. If the ``entry_point`` is invalid,
+the platform must return PSCI_E_INVALID_ADDRESS as error, which is
+propagated back to the normal world PSCI client.
+
+plat_psci_ops.get_sys_suspend_power_state()
+...........................................
+
+This function is called by the PSCI implementation during the ``SYSTEM_SUSPEND``
+call to get the ``req_state`` parameter from platform which encodes the power
+domain level specific local states to suspend to system affinity level. The
+``req_state`` will be utilized to do the PSCI state coordination and
+``pwr_domain_suspend()`` will be invoked with the coordinated target state to
+enter system suspend.
+
+plat_psci_ops.get_pwr_lvl_state_idx()
+.....................................
+
+This is an optional function and, if implemented, is invoked by the PSCI
+implementation to convert the ``local_state`` (first argument) at a specified
+``pwr_lvl`` (second argument) to an index between 0 and
+``PLAT_MAX_PWR_LVL_STATES`` - 1. This function is only needed if the platform
+supports more than two local power states at each power domain level, that is
+``PLAT_MAX_PWR_LVL_STATES`` is greater than 2, and needs to account for these
+local power states.
+
+plat_psci_ops.translate_power_state_by_mpidr()
+..............................................
+
+This is an optional function and, if implemented, verifies the ``power_state``
+(second argument) parameter of the PSCI API corresponding to a target power
+domain. The target power domain is identified by using both ``MPIDR`` (first
+argument) and the power domain level encoded in ``power_state``. The power domain
+level specific local states are to be extracted from ``power_state`` and be
+populated in the ``output_state`` (third argument) array. The functionality
+is similar to the ``validate_power_state`` function described above and is
+envisaged to be used in case the validity of ``power_state`` depend on the
+targeted power domain. If the ``power_state`` is invalid for the targeted power
+domain, the platform must return PSCI_E_INVALID_PARAMS as error. If this
+function is not implemented, then the generic implementation relies on
+``validate_power_state`` function to translate the ``power_state``.
+
+This function can also be used in case the platform wants to support local
+power state encoding for ``power_state`` parameter of PSCI_STAT_COUNT/RESIDENCY
+APIs as described in Section 5.18 of `PSCI`_.
+
+plat_psci_ops.get_node_hw_state()
+.................................
+
+This is an optional function. If implemented this function is intended to return
+the power state of a node (identified by the first parameter, the ``MPIDR``) in
+the power domain topology (identified by the second parameter, ``power_level``),
+as retrieved from a power controller or equivalent component on the platform.
+Upon successful completion, the implementation must map and return the final
+status among ``HW_ON``, ``HW_OFF`` or ``HW_STANDBY``. Upon encountering failures, it
+must return either ``PSCI_E_INVALID_PARAMS`` or ``PSCI_E_NOT_SUPPORTED`` as
+appropriate.
+
+Implementations are not expected to handle ``power_levels`` greater than
+``PLAT_MAX_PWR_LVL``.
+
+plat_psci_ops.system_reset2()
+.............................
+
+This is an optional function. If implemented this function is
+called during the ``SYSTEM_RESET2`` call to perform a reset
+based on the first parameter ``reset_type`` as specified in
+`PSCI`_. The parameter ``cookie`` can be used to pass additional
+reset information. If the ``reset_type`` is not supported, the
+function must return ``PSCI_E_NOT_SUPPORTED``. For architectural
+resets, all failures must return ``PSCI_E_INVALID_PARAMETERS``
+and vendor reset can return other PSCI error codes as defined
+in `PSCI`_. On success this function will not return.
+
+plat_psci_ops.write_mem_protect()
+.................................
+
+This is an optional function. If implemented it enables or disables the
+``MEM_PROTECT`` functionality based on the value of ``val``.
+A non-zero value enables ``MEM_PROTECT`` and a value of zero
+disables it. Upon encountering failures it must return a negative value
+and on success it must return 0.
+
+plat_psci_ops.read_mem_protect()
+................................
+
+This is an optional function. If implemented it returns the current
+state of ``MEM_PROTECT`` via the ``val`` parameter. Upon encountering
+failures it must return a negative value and on success it must
+return 0.
+
+plat_psci_ops.mem_protect_chk()
+...............................
+
+This is an optional function. If implemented it checks if a memory
+region defined by a base address ``base`` and with a size of ``length``
+bytes is protected by ``MEM_PROTECT``. If the region is protected
+then it must return 0, otherwise it must return a negative number.
+
+Interrupt Management framework (in BL31)
+----------------------------------------
+
+BL31 implements an Interrupt Management Framework (IMF) to manage interrupts
+generated in either security state and targeted to EL1 or EL2 in the non-secure
+state or EL3/S-EL1 in the secure state. The design of this framework is
+described in the `IMF Design Guide`_
+
+A platform should export the following APIs to support the IMF. The following
+text briefly describes each API and its implementation in Arm standard
+platforms. The API implementation depends upon the type of interrupt controller
+present in the platform. Arm standard platform layer supports both
+`Arm Generic Interrupt Controller version 2.0 (GICv2)`_
+and `3.0 (GICv3)`_. Juno builds the Arm platform layer to use GICv2 and the
+FVP can be configured to use either GICv2 or GICv3 depending on the build flag
+``FVP_USE_GIC_DRIVER`` (See FVP platform specific build options in
+`User Guide`_ for more details).
+
+See also: `Interrupt Controller Abstraction APIs`__.
+
+.. __: ../design/platform-interrupt-controller-API.rst
+
+Function : plat_interrupt_type_to_line() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uint32_t, uint32_t
+ Return : uint32_t
+
+The Arm processor signals an interrupt exception either through the IRQ or FIQ
+interrupt line. The specific line that is signaled depends on how the interrupt
+controller (IC) reports different interrupt types from an execution context in
+either security state. The IMF uses this API to determine which interrupt line
+the platform IC uses to signal each type of interrupt supported by the framework
+from a given security state. This API must be invoked at EL3.
+
+The first parameter will be one of the ``INTR_TYPE_*`` values (see
+`IMF Design Guide`_) indicating the target type of the interrupt, the second parameter is the
+security state of the originating execution context. The return result is the
+bit position in the ``SCR_EL3`` register of the respective interrupt trap: IRQ=1,
+FIQ=2.
+
+In the case of Arm standard platforms using GICv2, S-EL1 interrupts are
+configured as FIQs and Non-secure interrupts as IRQs from either security
+state.
+
+In the case of Arm standard platforms using GICv3, the interrupt line to be
+configured depends on the security state of the execution context when the
+interrupt is signalled and are as follows:
+
+- The S-EL1 interrupts are signaled as IRQ in S-EL0/1 context and as FIQ in
+ NS-EL0/1/2 context.
+- The Non secure interrupts are signaled as FIQ in S-EL0/1 context and as IRQ
+ in the NS-EL0/1/2 context.
+- The EL3 interrupts are signaled as FIQ in both S-EL0/1 and NS-EL0/1/2
+ context.
+
+Function : plat_ic_get_pending_interrupt_type() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : uint32_t
+
+This API returns the type of the highest priority pending interrupt at the
+platform IC. The IMF uses the interrupt type to retrieve the corresponding
+handler function. ``INTR_TYPE_INVAL`` is returned when there is no interrupt
+pending. The valid interrupt types that can be returned are ``INTR_TYPE_EL3``,
+``INTR_TYPE_S_EL1`` and ``INTR_TYPE_NS``. This API must be invoked at EL3.
+
+In the case of Arm standard platforms using GICv2, the *Highest Priority
+Pending Interrupt Register* (``GICC_HPPIR``) is read to determine the id of
+the pending interrupt. The type of interrupt depends upon the id value as
+follows.
+
+#. id < 1022 is reported as a S-EL1 interrupt
+#. id = 1022 is reported as a Non-secure interrupt.
+#. id = 1023 is reported as an invalid interrupt type.
+
+In the case of Arm standard platforms using GICv3, the system register
+``ICC_HPPIR0_EL1``, *Highest Priority Pending group 0 Interrupt Register*,
+is read to determine the id of the pending interrupt. The type of interrupt
+depends upon the id value as follows.
+
+#. id = ``PENDING_G1S_INTID`` (1020) is reported as a S-EL1 interrupt
+#. id = ``PENDING_G1NS_INTID`` (1021) is reported as a Non-secure interrupt.
+#. id = ``GIC_SPURIOUS_INTERRUPT`` (1023) is reported as an invalid interrupt type.
+#. All other interrupt id's are reported as EL3 interrupt.
+
+Function : plat_ic_get_pending_interrupt_id() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : uint32_t
+
+This API returns the id of the highest priority pending interrupt at the
+platform IC. ``INTR_ID_UNAVAILABLE`` is returned when there is no interrupt
+pending.
+
+In the case of Arm standard platforms using GICv2, the *Highest Priority
+Pending Interrupt Register* (``GICC_HPPIR``) is read to determine the id of the
+pending interrupt. The id that is returned by API depends upon the value of
+the id read from the interrupt controller as follows.
+
+#. id < 1022. id is returned as is.
+#. id = 1022. The *Aliased Highest Priority Pending Interrupt Register*
+ (``GICC_AHPPIR``) is read to determine the id of the non-secure interrupt.
+ This id is returned by the API.
+#. id = 1023. ``INTR_ID_UNAVAILABLE`` is returned.
+
+In the case of Arm standard platforms using GICv3, if the API is invoked from
+EL3, the system register ``ICC_HPPIR0_EL1``, *Highest Priority Pending Interrupt
+group 0 Register*, is read to determine the id of the pending interrupt. The id
+that is returned by API depends upon the value of the id read from the
+interrupt controller as follows.
+
+#. id < ``PENDING_G1S_INTID`` (1020). id is returned as is.
+#. id = ``PENDING_G1S_INTID`` (1020) or ``PENDING_G1NS_INTID`` (1021). The system
+ register ``ICC_HPPIR1_EL1``, *Highest Priority Pending Interrupt group 1
+ Register* is read to determine the id of the group 1 interrupt. This id
+ is returned by the API as long as it is a valid interrupt id
+#. If the id is any of the special interrupt identifiers,
+ ``INTR_ID_UNAVAILABLE`` is returned.
+
+When the API invoked from S-EL1 for GICv3 systems, the id read from system
+register ``ICC_HPPIR1_EL1``, *Highest Priority Pending group 1 Interrupt
+Register*, is returned if is not equal to GIC_SPURIOUS_INTERRUPT (1023) else
+``INTR_ID_UNAVAILABLE`` is returned.
+
+Function : plat_ic_acknowledge_interrupt() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : uint32_t
+
+This API is used by the CPU to indicate to the platform IC that processing of
+the highest pending interrupt has begun. It should return the raw, unmodified
+value obtained from the interrupt controller when acknowledging an interrupt.
+The actual interrupt number shall be extracted from this raw value using the API
+`plat_ic_get_interrupt_id()`__.
+
+.. __: ../design/platform-interrupt-controller-API.rst#function-unsigned-int-plat-ic-get-interrupt-id-unsigned-int-raw-optional
+
+This function in Arm standard platforms using GICv2, reads the *Interrupt
+Acknowledge Register* (``GICC_IAR``). This changes the state of the highest
+priority pending interrupt from pending to active in the interrupt controller.
+It returns the value read from the ``GICC_IAR``, unmodified.
+
+In the case of Arm standard platforms using GICv3, if the API is invoked
+from EL3, the function reads the system register ``ICC_IAR0_EL1``, *Interrupt
+Acknowledge Register group 0*. If the API is invoked from S-EL1, the function
+reads the system register ``ICC_IAR1_EL1``, *Interrupt Acknowledge Register
+group 1*. The read changes the state of the highest pending interrupt from
+pending to active in the interrupt controller. The value read is returned
+unmodified.
+
+The TSP uses this API to start processing of the secure physical timer
+interrupt.
+
+Function : plat_ic_end_of_interrupt() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uint32_t
+ Return : void
+
+This API is used by the CPU to indicate to the platform IC that processing of
+the interrupt corresponding to the id (passed as the parameter) has
+finished. The id should be the same as the id returned by the
+``plat_ic_acknowledge_interrupt()`` API.
+
+Arm standard platforms write the id to the *End of Interrupt Register*
+(``GICC_EOIR``) in case of GICv2, and to ``ICC_EOIR0_EL1`` or ``ICC_EOIR1_EL1``
+system register in case of GICv3 depending on where the API is invoked from,
+EL3 or S-EL1. This deactivates the corresponding interrupt in the interrupt
+controller.
+
+The TSP uses this API to finish processing of the secure physical timer
+interrupt.
+
+Function : plat_ic_get_interrupt_type() [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uint32_t
+ Return : uint32_t
+
+This API returns the type of the interrupt id passed as the parameter.
+``INTR_TYPE_INVAL`` is returned if the id is invalid. If the id is valid, a valid
+interrupt type (one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1`` and ``INTR_TYPE_NS``) is
+returned depending upon how the interrupt has been configured by the platform
+IC. This API must be invoked at EL3.
+
+Arm standard platforms using GICv2 configures S-EL1 interrupts as Group0 interrupts
+and Non-secure interrupts as Group1 interrupts. It reads the group value
+corresponding to the interrupt id from the relevant *Interrupt Group Register*
+(``GICD_IGROUPRn``). It uses the group value to determine the type of interrupt.
+
+In the case of Arm standard platforms using GICv3, both the *Interrupt Group
+Register* (``GICD_IGROUPRn``) and *Interrupt Group Modifier Register*
+(``GICD_IGRPMODRn``) is read to figure out whether the interrupt is configured
+as Group 0 secure interrupt, Group 1 secure interrupt or Group 1 NS interrupt.
+
+Crash Reporting mechanism (in BL31)
+-----------------------------------
+
+BL31 implements a crash reporting mechanism which prints the various registers
+of the CPU to enable quick crash analysis and debugging. This mechanism relies
+on the platform implementing ``plat_crash_console_init``,
+``plat_crash_console_putc`` and ``plat_crash_console_flush``.
+
+The file ``plat/common/aarch64/crash_console_helpers.S`` contains sample
+implementation of all of them. Platforms may include this file to their
+makefiles in order to benefit from them. By default, they will cause the crash
+output to be routed over the normal console infrastructure and get printed on
+consoles configured to output in crash state. ``console_set_scope()`` can be
+used to control whether a console is used for crash output.
+NOTE: Platforms are responsible for making sure that they only mark consoles for
+use in the crash scope that are able to support this, i.e. that are written in
+assembly and conform with the register clobber rules for putc() (x0-x2, x16-x17)
+and flush() (x0-x3, x16-x17) crash callbacks.
+
+In some cases (such as debugging very early crashes that happen before the
+normal boot console can be set up), platforms may want to control crash output
+more explicitly. These platforms may instead provide custom implementations for
+these. They are executed outside of a C environment and without a stack. Many
+console drivers provide functions named ``console_xxx_core_init/putc/flush``
+that are designed to be used by these functions. See Arm platforms (like juno)
+for an example of this.
+
+Function : plat_crash_console_init [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : int
+
+This API is used by the crash reporting mechanism to initialize the crash
+console. It must only use the general purpose registers x0 through x7 to do the
+initialization and returns 1 on success.
+
+Function : plat_crash_console_putc [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Return : int
+
+This API is used by the crash reporting mechanism to print a character on the
+designated crash console. It must only use general purpose registers x1 and
+x2 to do its work. The parameter and the return value are in general purpose
+register x0.
+
+Function : plat_crash_console_flush [mandatory]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : int
+
+This API is used by the crash reporting mechanism to force write of all buffered
+data on the designated crash console. It should only use general purpose
+registers x0 through x5 to do its work. The return value is 0 on successful
+completion; otherwise the return value is -1.
+
+External Abort handling and RAS Support
+---------------------------------------
+
+Function : plat_ea_handler
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Argument : uint64_t
+ Argument : void *
+ Argument : void *
+ Argument : uint64_t
+ Return : void
+
+This function is invoked by the RAS framework for the platform to handle an
+External Abort received at EL3. The intention of the function is to attempt to
+resolve the cause of External Abort and return; if that's not possible, to
+initiate orderly shutdown of the system.
+
+The first parameter (``int ea_reason``) indicates the reason for External Abort.
+Its value is one of ``ERROR_EA_*`` constants defined in ``ea_handle.h``.
+
+The second parameter (``uint64_t syndrome``) is the respective syndrome
+presented to EL3 after having received the External Abort. Depending on the
+nature of the abort (as can be inferred from the ``ea_reason`` parameter), this
+can be the content of either ``ESR_EL3`` or ``DISR_EL1``.
+
+The third parameter (``void *cookie``) is unused for now. The fourth parameter
+(``void *handle``) is a pointer to the preempted context. The fifth parameter
+(``uint64_t flags``) indicates the preempted security state. These parameters
+are received from the top-level exception handler.
+
+If ``RAS_EXTENSION`` is set to ``1``, the default implementation of this
+function iterates through RAS handlers registered by the platform. If any of the
+RAS handlers resolve the External Abort, no further action is taken.
+
+If ``RAS_EXTENSION`` is set to ``0``, or if none of the platform RAS handlers
+could resolve the External Abort, the default implementation prints an error
+message, and panics.
+
+Function : plat_handle_uncontainable_ea
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Argument : uint64_t
+ Return : void
+
+This function is invoked by the RAS framework when an External Abort of
+Uncontainable type is received at EL3. Due to the critical nature of
+Uncontainable errors, the intention of this function is to initiate orderly
+shutdown of the system, and is not expected to return.
+
+This function must be implemented in assembly.
+
+The first and second parameters are the same as that of ``plat_ea_handler``.
+
+The default implementation of this function calls
+``report_unhandled_exception``.
+
+Function : plat_handle_double_fault
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Argument : uint64_t
+ Return : void
+
+This function is invoked by the RAS framework when another External Abort is
+received at EL3 while one is already being handled. I.e., a call to
+``plat_ea_handler`` is outstanding. Due to its critical nature, the intention of
+this function is to initiate orderly shutdown of the system, and is not expected
+recover or return.
+
+This function must be implemented in assembly.
+
+The first and second parameters are the same as that of ``plat_ea_handler``.
+
+The default implementation of this function calls
+``report_unhandled_exception``.
+
+Function : plat_handle_el3_ea
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Return : void
+
+This function is invoked when an External Abort is received while executing in
+EL3. Due to its critical nature, the intention of this function is to initiate
+orderly shutdown of the system, and is not expected recover or return.
+
+This function must be implemented in assembly.
+
+The default implementation of this function calls
+``report_unhandled_exception``.
+
+Build flags
+-----------
+
+There are some build flags which can be defined by the platform to control
+inclusion or exclusion of certain BL stages from the FIP image. These flags
+need to be defined in the platform makefile which will get included by the
+build system.
+
+- **NEED_BL33**
+ By default, this flag is defined ``yes`` by the build system and ``BL33``
+ build option should be supplied as a build option. The platform has the
+ option of excluding the BL33 image in the ``fip`` image by defining this flag
+ to ``no``. If any of the options ``EL3_PAYLOAD_BASE`` or ``PRELOADED_BL33_BASE``
+ are used, this flag will be set to ``no`` automatically.
+
+C Library
+---------
+
+To avoid subtle toolchain behavioral dependencies, the header files provided
+by the compiler are not used. The software is built with the ``-nostdinc`` flag
+to ensure no headers are included from the toolchain inadvertently. Instead the
+required headers are included in the TF-A source tree. The library only
+contains those C library definitions required by the local implementation. If
+more functionality is required, the needed library functions will need to be
+added to the local implementation.
+
+Some C headers have been obtained from `FreeBSD`_ and `SCC`_, while others have
+been written specifically for TF-A. Fome implementation files have been obtained
+from `FreeBSD`_, others have been written specifically for TF-A as well. The
+files can be found in ``include/lib/libc`` and ``lib/libc``.
+
+SCC can be found in http://www.simple-cc.org/. A copy of the `FreeBSD`_ sources
+can be obtained from http://github.com/freebsd/freebsd.
+
+Storage abstraction layer
+-------------------------
+
+In order to improve platform independence and portability an storage abstraction
+layer is used to load data from non-volatile platform storage.
+
+Each platform should register devices and their drivers via the Storage layer.
+These drivers then need to be initialized by bootloader phases as
+required in their respective ``blx_platform_setup()`` functions. Currently
+storage access is only required by BL1 and BL2 phases. The ``load_image()``
+function uses the storage layer to access non-volatile platform storage.
+
+It is mandatory to implement at least one storage driver. For the Arm
+development platforms the Firmware Image Package (FIP) driver is provided as
+the default means to load data from storage (see the "Firmware Image Package"
+section in the `User Guide`_). The storage layer is described in the header file
+``include/drivers/io/io_storage.h``. The implementation of the common library
+is in ``drivers/io/io_storage.c`` and the driver files are located in
+``drivers/io/``.
+
+Each IO driver must provide ``io_dev_*`` structures, as described in
+``drivers/io/io_driver.h``. These are returned via a mandatory registration
+function that is called on platform initialization. The semi-hosting driver
+implementation in ``io_semihosting.c`` can be used as an example.
+
+The Storage layer provides mechanisms to initialize storage devices before
+IO operations are called. The basic operations supported by the layer
+include ``open()``, ``close()``, ``read()``, ``write()``, ``size()`` and ``seek()``.
+Drivers do not have to implement all operations, but each platform must
+provide at least one driver for a device capable of supporting generic
+operations such as loading a bootloader image.
+
+The current implementation only allows for known images to be loaded by the
+firmware. These images are specified by using their identifiers, as defined in
+``include/plat/common/common_def.h`` (or a separate header file included from
+there). The platform layer (``plat_get_image_source()``) then returns a reference
+to a device and a driver-specific ``spec`` which will be understood by the driver
+to allow access to the image data.
+
+The layer is designed in such a way that is it possible to chain drivers with
+other drivers. For example, file-system drivers may be implemented on top of
+physical block devices, both represented by IO devices with corresponding
+drivers. In such a case, the file-system "binding" with the block device may
+be deferred until the file-system device is initialised.
+
+The abstraction currently depends on structures being statically allocated
+by the drivers and callers, as the system does not yet provide a means of
+dynamically allocating memory. This may also have the affect of limiting the
+amount of open resources per driver.
+
+--------------
+
+*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _include/plat/common/platform.h: ../include/plat/common/platform.h
+.. _include/plat/arm/common/plat_arm.h: ../include/plat/arm/common/plat_arm.h%5D
+.. _User Guide: user-guide.rst
+.. _include/plat/common/common_def.h: ../include/plat/common/common_def.h
+.. _include/plat/arm/common/arm_def.h: ../include/plat/arm/common/arm_def.h
+.. _plat/common/aarch64/platform_mp_stack.S: ../plat/common/aarch64/platform_mp_stack.S
+.. _plat/common/aarch64/platform_up_stack.S: ../plat/common/aarch64/platform_up_stack.S
+.. _For example, define the build flag in platform.mk: PLAT_PL061_MAX_GPIOS%20:=%20160
+.. _Power Domain Topology Design: psci-pd-tree.rst
+.. _include/common/bl_common.h: ../include/common/bl_common.h
+.. _include/lib/aarch32/arch.h: ../include/lib/aarch32/arch.h
+.. _Firmware Design: firmware-design.rst
+.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
+.. _plat/arm/board/fvp/fvp_pm.c: ../plat/arm/board/fvp/fvp_pm.c
+.. _Platform compatibility policy: ./platform-compatibility-policy.rst
+.. _IMF Design Guide: interrupt-framework-design.rst
+.. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
+.. _3.0 (GICv3): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0069b/index.html
+.. _FreeBSD: https://www.freebsd.org
+.. _SCC: http://www.simple-cc.org/
--- /dev/null
+PSCI Library Integration guide for Armv8-A AArch32 systems
+==========================================================
+
+
+
+.. contents::
+
+This document describes the PSCI library interface with a focus on how to
+integrate with a suitable Trusted OS for an Armv8-A AArch32 system. The PSCI
+Library implements the PSCI Standard as described in `PSCI spec`_ and is meant
+to be integrated with EL3 Runtime Software which invokes the PSCI Library
+interface appropriately. **EL3 Runtime Software** refers to software executing
+at the highest secure privileged mode, which is EL3 in AArch64 or Secure SVC/
+Monitor mode in AArch32, and provides runtime services to the non-secure world.
+The runtime service request is made via SMC (Secure Monitor Call) and the call
+must adhere to `SMCCC`_. In AArch32, EL3 Runtime Software may additionally
+include Trusted OS functionality. A minimal AArch32 Secure Payload, SP-MIN, is
+provided in Trusted Firmware-A (TF-A) to illustrate the usage and integration
+of the PSCI library. The description of PSCI library interface and its
+integration with EL3 Runtime Software in this document is targeted towards
+AArch32 systems.
+
+Generic call sequence for PSCI Library interface (AArch32)
+----------------------------------------------------------
+
+The generic call sequence of PSCI Library interfaces (see
+`PSCI Library Interface`_) during cold boot in AArch32
+system is described below:
+
+#. After cold reset, the EL3 Runtime Software performs its cold boot
+ initialization including the PSCI library pre-requisites mentioned in
+ `PSCI Library Interface`_, and also the necessary platform
+ setup.
+
+#. Call ``psci_setup()`` in Monitor mode.
+
+#. Optionally call ``psci_register_spd_pm_hook()`` to register callbacks to
+ do bookkeeping for the EL3 Runtime Software during power management.
+
+#. Call ``psci_prepare_next_non_secure_ctx()`` to initialize the non-secure CPU
+ context.
+
+#. Get the non-secure ``cpu_context_t`` for the current CPU by calling
+ ``cm_get_context()`` , then programming the registers in the non-secure
+ context and exiting to non-secure world. If the EL3 Runtime Software needs
+ additional configuration to be set for non-secure context, like routing
+ FIQs to the secure world, the values of the registers can be modified prior
+ to programming. See `PSCI CPU context management`_ for more
+ details on CPU context management.
+
+The generic call sequence of PSCI library interfaces during warm boot in
+AArch32 systems is described below:
+
+#. After warm reset, the EL3 Runtime Software performs the necessary warm
+ boot initialization including the PSCI library pre-requisites mentioned in
+ `PSCI Library Interface`_ (Note that the Data cache
+ **must not** be enabled).
+
+#. Call ``psci_warmboot_entrypoint()`` in Monitor mode. This interface
+ initializes/restores the non-secure CPU context as well.
+
+#. Do step 5 of the cold boot call sequence described above.
+
+The generic call sequence of PSCI library interfaces on receipt of a PSCI SMC
+on an AArch32 system is described below:
+
+#. On receipt of an SMC, save the register context as per `SMCCC`_.
+
+#. If the SMC function identifier corresponds to a SMC32 PSCI API, construct
+ the appropriate arguments and call the ``psci_smc_handler()`` interface.
+ The invocation may or may not return back to the caller depending on
+ whether the PSCI API resulted in power down of the CPU.
+
+#. If ``psci_smc_handler()`` returns, populate the return value in R0 (AArch32)/
+ X0 (AArch64) and restore other registers as per `SMCCC`_.
+
+PSCI CPU context management
+---------------------------
+
+PSCI library is in charge of initializing/restoring the non-secure CPU system
+registers according to `PSCI specification`_ during cold/warm boot.
+This is referred to as ``PSCI CPU Context Management``. Registers that need to
+be preserved across CPU power down/power up cycles are maintained in
+``cpu_context_t`` data structure. The initialization of other non-secure CPU
+system registers which do not require coordination with the EL3 Runtime
+Software is done directly by the PSCI library (see ``cm_prepare_el3_exit()``).
+
+The EL3 Runtime Software is responsible for managing register context
+during switch between Normal and Secure worlds. The register context to be
+saved and restored depends on the mechanism used to trigger the world switch.
+For example, if the world switch was triggered by an SMC call, then the
+registers need to be saved and restored according to `SMCCC`_. In AArch64,
+due to the tight integration with BL31, both BL31 and PSCI library
+use the same ``cpu_context_t`` data structure for PSCI CPU context management
+and register context management during world switch. This cannot be assumed
+for AArch32 EL3 Runtime Software since most AArch32 Trusted OSes already implement
+a mechanism for register context management during world switch. Hence, when
+the PSCI library is integrated with a AArch32 EL3 Runtime Software, the
+``cpu_context_t`` is stripped down for just PSCI CPU context management.
+
+During cold/warm boot, after invoking appropriate PSCI library interfaces, it
+is expected that the EL3 Runtime Software will query the ``cpu_context_t`` and
+write appropriate values to the corresponding system registers. This mechanism
+resolves 2 additional problems for AArch32 EL3 Runtime Software:
+
+#. Values for certain system registers like SCR and SCTLR cannot be
+ unilaterally determined by PSCI library and need inputs from the EL3
+ Runtime Software. Using ``cpu_context_t`` as an intermediary data store
+ allows EL3 Runtime Software to modify the register values appropriately
+ before programming them.
+
+#. The PSCI library provides appropriate LR and SPSR values (entrypoint
+ information) for exit into non-secure world. Using ``cpu_context_t`` as an
+ intermediary data store allows the EL3 Runtime Software to store these
+ values safely until it is ready for exit to non-secure world.
+
+Currently the ``cpu_context_t`` data structure for AArch32 stores the following
+registers: R0 - R3, LR (R14), SCR, SPSR, SCTLR.
+
+The EL3 Runtime Software must implement accessors to get/set pointers
+to CPU context ``cpu_context_t`` data and these are described in
+`CPU Context management API`_.
+
+PSCI Library Interface
+----------------------
+
+The PSCI library implements the `PSCI Specification`_. The interfaces
+to this library are declared in ``psci_lib.h`` and are as listed below:
+
+.. code:: c
+
+ u_register_t psci_smc_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, void *cookie,
+ void *handle, u_register_t flags);
+ int psci_setup(const psci_lib_args_t *lib_args);
+ void psci_warmboot_entrypoint(void);
+ void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
+ void psci_prepare_next_non_secure_ctx(entry_point_info_t *next_image_info);
+
+The CPU context data 'cpu_context_t' is programmed to the registers differently
+when PSCI is integrated with an AArch32 EL3 Runtime Software compared to
+when the PSCI is integrated with an AArch64 EL3 Runtime Software (BL31). For
+example, in the case of AArch64, there is no need to retrieve ``cpu_context_t``
+data and program the registers as it will done implicitly as part of
+``el3_exit``. The description below of the PSCI interfaces is targeted at
+integration with an AArch32 EL3 Runtime Software.
+
+The PSCI library is responsible for initializing/restoring the non-secure world
+to an appropriate state after boot and may choose to directly program the
+non-secure system registers. The PSCI generic code takes care not to directly
+modify any of the system registers affecting the secure world and instead
+returns the values to be programmed to these registers via ``cpu_context_t``.
+The EL3 Runtime Software is responsible for programming those registers and
+can use the proposed values provided in the ``cpu_context_t``, modifying the
+values if required.
+
+PSCI library needs the flexibility to access both secure and non-secure
+copies of banked registers. Hence it needs to be invoked in Monitor mode
+for AArch32 and in EL3 for AArch64. The NS bit in SCR (in AArch32) or SCR_EL3
+(in AArch64) must be set to 0. Additional requirements for the PSCI library
+interfaces are:
+
+- Instruction cache must be enabled
+- Both IRQ and FIQ must be masked for the current CPU
+- The page tables must be setup and the MMU enabled
+- The C runtime environment must be setup and stack initialized
+- The Data cache must be enabled prior to invoking any of the PSCI library
+ interfaces except for ``psci_warmboot_entrypoint()``. For
+ ``psci_warmboot_entrypoint()``, if the build option ``HW_ASSISTED_COHERENCY``
+ is enabled however, data caches are expected to be enabled.
+
+Further requirements for each interface can be found in the interface
+description.
+
+Interface : psci_setup()
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : const psci_lib_args_t *lib_args
+ Return : void
+
+This function is to be called by the primary CPU during cold boot before
+any other interface to the PSCI library. It takes ``lib_args``, a const pointer
+to ``psci_lib_args_t``, as the argument. The ``psci_lib_args_t`` is a versioned
+structure and is declared in ``psci_lib.h`` header as follows:
+
+.. code:: c
+
+ typedef struct psci_lib_args {
+ /* The version information of PSCI Library Interface */
+ param_header_t h;
+ /* The warm boot entrypoint function */
+ mailbox_entrypoint_t mailbox_ep;
+ } psci_lib_args_t;
+
+The first field ``h``, of ``param_header_t`` type, provides the version
+information. The second field ``mailbox_ep`` is the warm boot entrypoint address
+and is used to configure the platform mailbox. Helper macros are provided in
+``psci_lib.h`` to construct the ``lib_args`` argument statically or during
+runtime. Prior to calling the ``psci_setup()`` interface, the platform setup for
+cold boot must have completed. Major actions performed by this interface are:
+
+- Initializes architecture.
+- Initializes PSCI power domain and state coordination data structures.
+- Calls ``plat_setup_psci_ops()`` with warm boot entrypoint ``mailbox_ep`` as
+ argument.
+- Calls ``cm_set_context_by_index()`` (see
+ `CPU Context management API`_) for all the CPUs in the
+ platform
+
+Interface : psci_prepare_next_non_secure_ctx()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : entry_point_info_t *next_image_info
+ Return : void
+
+After ``psci_setup()`` and prior to exit to the non-secure world, this function
+must be called by the EL3 Runtime Software to initialize the non-secure world
+context. The non-secure world entrypoint information ``next_image_info`` (first
+argument) will be used to determine the non-secure context. After this function
+returns, the EL3 Runtime Software must retrieve the ``cpu_context_t`` (using
+cm_get_context()) for the current CPU and program the registers prior to exit
+to the non-secure world.
+
+Interface : psci_register_spd_pm_hook()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : const spd_pm_ops_t *
+ Return : void
+
+As explained in `Secure payload power management callback`_,
+the EL3 Runtime Software may want to perform some bookkeeping during power
+management operations. This function is used to register the ``spd_pm_ops_t``
+(first argument) callbacks with the PSCI library which will be called
+appropriately during power management. Calling this function is optional and
+need to be called by the primary CPU during the cold boot sequence after
+``psci_setup()`` has completed.
+
+Interface : psci_smc_handler()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4, void *cookie,
+ void *handle, u_register_t flags
+ Return : u_register_t
+
+This function is the top level handler for SMCs which fall within the
+PSCI service range specified in `SMCCC`_. The function ID ``smc_fid`` (first
+argument) determines the PSCI API to be called. The ``x1`` to ``x4`` (2nd to 5th
+arguments), are the values of the registers r1 - r4 (in AArch32) or x1 - x4
+(in AArch64) when the SMC is received. These are the arguments to PSCI API as
+described in `PSCI spec`_. The 'flags' (8th argument) is a bit field parameter
+and is detailed in 'smccc.h' header. It includes whether the call is from the
+secure or non-secure world. The ``cookie`` (6th argument) and the ``handle``
+(7th argument) are not used and are reserved for future use.
+
+The return value from this interface is the return value from the underlying
+PSCI API corresponding to ``smc_fid``. This function may not return back to the
+caller if PSCI API causes power down of the CPU. In this case, when the CPU
+wakes up, it will start execution from the warm reset address.
+
+Interface : psci_warmboot_entrypoint()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : void
+ Return : void
+
+This function performs the warm boot initialization/restoration as mandated by
+`PSCI spec`_. For AArch32, on wakeup from power down the CPU resets to secure SVC
+mode and the EL3 Runtime Software must perform the prerequisite initializations
+mentioned at top of this section. This function must be called with Data cache
+disabled (unless build option ``HW_ASSISTED_COHERENCY`` is enabled) but with MMU
+initialized and enabled. The major actions performed by this function are:
+
+- Invalidates the stack and enables the data cache.
+- Initializes architecture and PSCI state coordination.
+- Restores/Initializes the peripheral drivers to the required state via
+ appropriate ``plat_psci_ops_t`` hooks
+- Restores the EL3 Runtime Software context via appropriate ``spd_pm_ops_t``
+ callbacks.
+- Restores/Initializes the non-secure context and populates the
+ ``cpu_context_t`` for the current CPU.
+
+Upon the return of this function, the EL3 Runtime Software must retrieve the
+non-secure ``cpu_context_t`` using ``cm_get_context()`` and program the registers
+prior to exit to the non-secure world.
+
+EL3 Runtime Software dependencies
+---------------------------------
+
+The PSCI Library includes supporting frameworks like context management,
+cpu operations (cpu_ops) and per-cpu data framework. Other helper library
+functions like bakery locks and spin locks are also included in the library.
+The dependencies which must be fulfilled by the EL3 Runtime Software
+for integration with PSCI library are described below.
+
+General dependencies
+~~~~~~~~~~~~~~~~~~~~
+
+The PSCI library being a Multiprocessor (MP) implementation, EL3 Runtime
+Software must provide an SMC handling framework capable of MP adhering to
+`SMCCC`_ specification.
+
+The EL3 Runtime Software must also export cache maintenance primitives
+and some helper utilities for assert, print and memory operations as listed
+below. The TF-A source tree provides implementations for all
+these functions but the EL3 Runtime Software may use its own implementation.
+
+**Functions : assert(), memcpy(), memset(), printf()**
+
+These must be implemented as described in ISO C Standard.
+
+**Function : flush_dcache_range()**
+
+::
+
+ Argument : uintptr_t addr, size_t size
+ Return : void
+
+This function cleans and invalidates (flushes) the data cache for memory
+at address ``addr`` (first argument) address and of size ``size`` (second argument).
+
+**Function : inv_dcache_range()**
+
+::
+
+ Argument : uintptr_t addr, size_t size
+ Return : void
+
+This function invalidates (flushes) the data cache for memory at address
+``addr`` (first argument) address and of size ``size`` (second argument).
+
+**Function : do_panic()**
+
+::
+
+ Argument : void
+ Return : void
+
+This function will be called by the PSCI library on encountering a critical
+failure that cannot be recovered from. This function **must not** return.
+
+CPU Context management API
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The CPU context management data memory is statically allocated by PSCI library
+in BSS section. The PSCI library requires the EL3 Runtime Software to implement
+APIs to store and retrieve pointers to this CPU context data. SP-MIN
+demonstrates how these APIs can be implemented but the EL3 Runtime Software can
+choose a more optimal implementation (like dedicating the secure TPIDRPRW
+system register (in AArch32) for storing these pointers).
+
+**Function : cm_set_context_by_index()**
+
+::
+
+ Argument : unsigned int cpu_idx, void *context, unsigned int security_state
+ Return : void
+
+This function is called during cold boot when the ``psci_setup()`` PSCI library
+interface is called.
+
+This function must store the pointer to the CPU context data, ``context`` (2nd
+argument), for the specified ``security_state`` (3rd argument) and CPU identified
+by ``cpu_idx`` (first argument). The ``security_state`` will always be non-secure
+when called by PSCI library and this argument is retained for compatibility
+with BL31. The ``cpu_idx`` will correspond to the index returned by the
+``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU.
+
+The actual method of storing the ``context`` pointers is implementation specific.
+For example, SP-MIN stores the pointers in the array ``sp_min_cpu_ctx_ptr``
+declared in ``sp_min_main.c``.
+
+**Function : cm_get_context()**
+
+::
+
+ Argument : uint32_t security_state
+ Return : void *
+
+This function must return the pointer to the ``cpu_context_t`` structure for
+the specified ``security_state`` (first argument) for the current CPU. The caller
+must ensure that ``cm_set_context_by_index`` is called first and the appropriate
+context pointers are stored prior to invoking this API. The ``security_state``
+will always be non-secure when called by PSCI library and this argument
+is retained for compatibility with BL31.
+
+**Function : cm_get_context_by_index()**
+
+::
+
+ Argument : unsigned int cpu_idx, unsigned int security_state
+ Return : void *
+
+This function must return the pointer to the ``cpu_context_t`` structure for
+the specified ``security_state`` (second argument) for the CPU identified by
+``cpu_idx`` (first argument). The caller must ensure that
+``cm_set_context_by_index`` is called first and the appropriate context
+pointers are stored prior to invoking this API. The ``security_state`` will
+always be non-secure when called by PSCI library and this argument is
+retained for compatibility with BL31. The ``cpu_idx`` will correspond to the
+index returned by the ``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU.
+
+Platform API
+~~~~~~~~~~~~
+
+The platform layer abstracts the platform-specific details from the generic
+PSCI library. The following platform APIs/macros must be defined by the EL3
+Runtime Software for integration with the PSCI library.
+
+The mandatory platform APIs are:
+
+- plat_my_core_pos
+- plat_core_pos_by_mpidr
+- plat_get_syscnt_freq2
+- plat_get_power_domain_tree_desc
+- plat_setup_psci_ops
+- plat_reset_handler
+- plat_panic_handler
+- plat_get_my_stack
+
+The mandatory platform macros are:
+
+- PLATFORM_CORE_COUNT
+- PLAT_MAX_PWR_LVL
+- PLAT_NUM_PWR_DOMAINS
+- CACHE_WRITEBACK_GRANULE
+- PLAT_MAX_OFF_STATE
+- PLAT_MAX_RET_STATE
+- PLAT_MAX_PWR_LVL_STATES (optional)
+- PLAT_PCPU_DATA_SIZE (optional)
+
+The details of these APIs/macros can be found in `Porting Guide`_.
+
+All platform specific operations for power management are done via
+``plat_psci_ops_t`` callbacks registered by the platform when
+``plat_setup_psci_ops()`` API is called. The description of each of
+the callbacks in ``plat_psci_ops_t`` can be found in PSCI section of the
+`Porting Guide`_. If any these callbacks are not registered, then the
+PSCI API associated with that callback will not be supported by PSCI
+library.
+
+Secure payload power management callback
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+During PSCI power management operations, the EL3 Runtime Software may
+need to perform some bookkeeping, and PSCI library provides
+``spd_pm_ops_t`` callbacks for this purpose. These hooks must be
+populated and registered by using ``psci_register_spd_pm_hook()`` PSCI
+library interface.
+
+Typical bookkeeping during PSCI power management calls include save/restore
+of the EL3 Runtime Software context. Also if the EL3 Runtime Software makes
+use of secure interrupts, then these interrupts must also be managed
+appropriately during CPU power down/power up. Any secure interrupt targeted
+to the current CPU must be disabled or re-targeted to other running CPU prior
+to power down of the current CPU. During power up, these interrupt can be
+enabled/re-targeted back to the current CPU.
+
+.. code:: c
+
+ typedef struct spd_pm_ops {
+ void (*svc_on)(u_register_t target_cpu);
+ int32_t (*svc_off)(u_register_t __unused);
+ void (*svc_suspend)(u_register_t max_off_pwrlvl);
+ void (*svc_on_finish)(u_register_t __unused);
+ void (*svc_suspend_finish)(u_register_t max_off_pwrlvl);
+ int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu);
+ int32_t (*svc_migrate_info)(u_register_t *resident_cpu);
+ void (*svc_system_off)(void);
+ void (*svc_system_reset)(void);
+ } spd_pm_ops_t;
+
+A brief description of each callback is given below:
+
+- svc_on, svc_off, svc_on_finish
+
+ The ``svc_on``, ``svc_off`` callbacks are called during PSCI_CPU_ON,
+ PSCI_CPU_OFF APIs respectively. The ``svc_on_finish`` is called when the
+ target CPU of PSCI_CPU_ON API powers up and executes the
+ ``psci_warmboot_entrypoint()`` PSCI library interface.
+
+- svc_suspend, svc_suspend_finish
+
+ The ``svc_suspend`` callback is called during power down bu either
+ PSCI_SUSPEND or PSCI_SYSTEM_SUSPEND APIs. The ``svc_suspend_finish`` is
+ called when the CPU wakes up from suspend and executes the
+ ``psci_warmboot_entrypoint()`` PSCI library interface. The ``max_off_pwrlvl``
+ (first parameter) denotes the highest power domain level being powered down
+ to or woken up from suspend.
+
+- svc_system_off, svc_system_reset
+
+ These callbacks are called during PSCI_SYSTEM_OFF and PSCI_SYSTEM_RESET
+ PSCI APIs respectively.
+
+- svc_migrate_info
+
+ This callback is called in response to PSCI_MIGRATE_INFO_TYPE or
+ PSCI_MIGRATE_INFO_UP_CPU APIs. The return value of this callback must
+ correspond to the return value of PSCI_MIGRATE_INFO_TYPE API as described
+ in `PSCI spec`_. If the secure payload is a Uniprocessor (UP)
+ implementation, then it must update the mpidr of the CPU it is resident in
+ via ``resident_cpu`` (first argument). The updates to ``resident_cpu`` is
+ ignored if the secure payload is a multiprocessor (MP) implementation.
+
+- svc_migrate
+
+ This callback is only relevant if the secure payload in EL3 Runtime
+ Software is a Uniprocessor (UP) implementation and supports migration from
+ the current CPU ``from_cpu`` (first argument) to another CPU ``to_cpu``
+ (second argument). This callback is called in response to PSCI_MIGRATE
+ API. This callback is never called if the secure payload is a
+ Multiprocessor (MP) implementation.
+
+CPU operations
+~~~~~~~~~~~~~~
+
+The CPU operations (cpu_ops) framework implement power down sequence specific
+to the CPU and the details of which can be found in the
+``CPU specific operations framework`` section of `Firmware Design`_. The TF-A
+tree implements the ``cpu_ops`` for various supported CPUs and the EL3 Runtime
+Software needs to include the required ``cpu_ops`` in its build. The start and
+end of the ``cpu_ops`` descriptors must be exported by the EL3 Runtime Software
+via the ``__CPU_OPS_START__`` and ``__CPU_OPS_END__`` linker symbols.
+
+The ``cpu_ops`` descriptors also include reset sequences and may include errata
+workarounds for the CPU. The EL3 Runtime Software can choose to call this
+during cold/warm reset if it does not implement its own reset sequence/errata
+workarounds.
+
+--------------
+
+*Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _PSCI spec: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
+.. _SMCCC: https://silver.arm.com/download/ARM_and_AMBA_Architecture/AR570-DA-80002-r0p0-00rel0/ARM_DEN0028A_SMC_Calling_Convention.pdf
+.. _PSCI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
+.. _PSCI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
+.. _Porting Guide: ../getting_started/porting-guide.rst
+.. _Firmware Design: ../design/firmware-design.rst
--- /dev/null
+Trusted Firmware-A EL3 runtime service writer's guide
+=====================================================
+
+
+
+.. contents::
+
+Introduction
+------------
+
+This document describes how to add a runtime service to the EL3 Runtime
+Firmware component of Trusted Firmware-A (TF-A), BL31.
+
+Software executing in the normal world and in the trusted world at exception
+levels lower than EL3 will request runtime services using the Secure Monitor
+Call (SMC) instruction. These requests will follow the convention described in
+the SMC Calling Convention PDD (`SMCCC`_). The `SMCCC`_ assigns function
+identifiers to each SMC request and describes how arguments are passed and
+results are returned.
+
+SMC Functions are grouped together based on the implementor of the service, for
+example a subset of the Function IDs are designated as "OEM Calls" (see `SMCCC`_
+for full details). The EL3 runtime services framework in BL31 enables the
+independent implementation of services for each group, which are then compiled
+into the BL31 image. This simplifies the integration of common software from
+Arm to support `PSCI`_, Secure Monitor for a Trusted OS and SoC specific
+software. The common runtime services framework ensures that SMC Functions are
+dispatched to their respective service implementation - the `Firmware Design`_
+provides details of how this is achieved.
+
+The interface and operation of the runtime services depends heavily on the
+concepts and definitions described in the `SMCCC`_, in particular SMC Function
+IDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and
+SMC64 calling conventions. Please refer to that document for a full explanation
+of these terms.
+
+Owning Entities, Call Types and Function IDs
+--------------------------------------------
+
+The SMC Function Identifier includes a OEN field. These values and their
+meaning are described in `SMCCC`_ and summarized in table 1 below. Some entities
+are allocated a range of of OENs. The OEN must be interpreted in conjunction
+with the SMC call type, which is either *Fast* or *Yielding*. Fast calls are
+uninterruptible whereas Yielding calls can be pre-empted. The majority of
+Owning Entities only have allocated ranges for Fast calls: Yielding calls are
+reserved exclusively for Trusted OS providers or for interoperability with
+legacy 32-bit software that predates the `SMCCC`_.
+
+::
+
+ Type OEN Service
+ Fast 0 Arm Architecture calls
+ Fast 1 CPU Service calls
+ Fast 2 SiP Service calls
+ Fast 3 OEM Service calls
+ Fast 4 Standard Service calls
+ Fast 5-47 Reserved for future use
+ Fast 48-49 Trusted Application calls
+ Fast 50-63 Trusted OS calls
+
+ Yielding 0- 1 Reserved for existing Armv7-A calls
+ Yielding 2-63 Trusted OS Standard Calls
+
+*Table 1: Service types and their corresponding Owning Entity Numbers*
+
+Each individual entity can allocate the valid identifiers within the entity
+range as they need - it is not necessary to coordinate with other entities of
+the same type. For example, two SoC providers can use the same Function ID
+within the SiP Service calls OEN range to mean different things - as these
+calls should be specific to the SoC. The Standard Runtime Calls OEN is used for
+services defined by Arm standards, such as `PSCI`_.
+
+The SMC Function ID also indicates whether the call has followed the SMC32
+calling convention, where all parameters are 32-bit, or the SMC64 calling
+convention, where the parameters are 64-bit. The framework identifies and
+rejects invalid calls that use the SMC64 calling convention but that originate
+from an AArch32 caller.
+
+The EL3 runtime services framework uses the call type and OEN to identify a
+specific handler for each SMC call, but it is expected that an individual
+handler will be responsible for all SMC Functions within a given service type.
+
+Getting started
+---------------
+
+TF-A has a `services`_ directory in the source tree under which
+each owning entity can place the implementation of its runtime service. The
+`PSCI`_ implementation is located here in the `lib/psci`_ directory.
+
+Runtime service sources will need to include the `runtime_svc.h`_ header file.
+
+Registering a runtime service
+-----------------------------
+
+A runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying
+the name of the service, the range of OENs covered, the type of service and
+initialization and call handler functions.
+
+::
+
+ #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch)
+
+- ``_name`` is used to identify the data structure declared by this macro, and
+ is also used for diagnostic purposes
+
+- ``_start`` and ``_end`` values must be based on the ``OEN_*`` values defined in
+ `smccc.h`_
+
+- ``_type`` must be one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD``
+
+- ``_setup`` is the initialization function with the ``rt_svc_init`` signature:
+
+ .. code:: c
+
+ typedef int32_t (*rt_svc_init)(void);
+
+- ``_smch`` is the SMC handler function with the ``rt_svc_handle`` signature:
+
+ .. code:: c
+
+ typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
+ u_register_t x1, u_register_t x2,
+ u_register_t x3, u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags);
+
+Details of the requirements and behavior of the two callbacks is provided in
+the following sections.
+
+During initialization the services framework validates each declared service
+to ensure that the following conditions are met:
+
+#. The ``_start`` OEN is not greater than the ``_end`` OEN
+#. The ``_end`` OEN does not exceed the maximum OEN value (63)
+#. The ``_type`` is one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD``
+#. ``_setup`` and ``_smch`` routines have been specified
+
+`std_svc_setup.c`_ provides an example of registering a runtime service:
+
+.. code:: c
+
+ /* Register Standard Service Calls as runtime service */
+ DECLARE_RT_SVC(
+ std_svc,
+ OEN_STD_START,
+ OEN_STD_END,
+ SMC_TYPE_FAST,
+ std_svc_setup,
+ std_svc_smc_handler
+ );
+
+Initializing a runtime service
+------------------------------
+
+Runtime services are initialized once, during cold boot, by the primary CPU
+after platform and architectural initialization is complete. The framework
+performs basic validation of the declared service before calling
+the service initialization function (``_setup`` in the declaration). This
+function must carry out any essential EL3 initialization prior to receiving a
+SMC Function call via the handler function.
+
+On success, the initialization function must return ``0``. Any other return value
+will cause the framework to issue a diagnostic:
+
+::
+
+ Error initializing runtime service <name of the service>
+
+and then ignore the service - the system will continue to boot but SMC calls
+will not be passed to the service handler and instead return the *Unknown SMC
+Function ID* result ``0xFFFFFFFF``.
+
+If the system must not be allowed to proceed without the service, the
+initialization function must itself cause the firmware boot to be halted.
+
+If the service uses per-CPU data this must either be initialized for all CPUs
+during this call, or be done lazily when a CPU first issues an SMC call to that
+service.
+
+Handling runtime service requests
+---------------------------------
+
+SMC calls for a service are forwarded by the framework to the service's SMC
+handler function (``_smch`` in the service declaration). This function must have
+the following signature:
+
+.. code:: c
+
+ typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
+ u_register_t x1, u_register_t x2,
+ u_register_t x3, u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags);
+
+The handler is responsible for:
+
+#. Determining that ``smc_fid`` is a valid and supported SMC Function ID,
+ otherwise completing the request with the *Unknown SMC Function ID*:
+
+ .. code:: c
+
+ SMC_RET1(handle, SMC_UNK);
+
+#. Determining if the requested function is valid for the calling security
+ state. SMC Calls can be made from both the normal and trusted worlds and
+ the framework will forward all calls to the service handler.
+
+ The ``flags`` parameter to this function indicates the caller security state
+ in bit[0], where a value of ``1`` indicates a non-secure caller. The
+ ``is_caller_secure(flags)`` and ``is_caller_non_secure(flags)`` can be used to
+ test this condition.
+
+ If invalid, the request should be completed with:
+
+ .. code:: c
+
+ SMC_RET1(handle, SMC_UNK);
+
+#. Truncating parameters for calls made using the SMC32 calling convention.
+ Such calls can be determined by checking the CC field in bit[30] of the
+ ``smc_fid`` parameter, for example by using:
+
+ ::
+
+ if (GET_SMC_CC(smc_fid) == SMC_32) ...
+
+ For such calls, the upper bits of the parameters x1-x4 and the saved
+ parameters X5-X7 are UNDEFINED and must be explicitly ignored by the
+ handler. This can be done by truncating the values to a suitable 32-bit
+ integer type before use, for example by ensuring that functions defined
+ to handle individual SMC Functions use appropriate 32-bit parameters.
+
+#. Providing the service requested by the SMC Function, utilizing the
+ immediate parameters x1-x4 and/or the additional saved parameters X5-X7.
+ The latter can be retrieved using the ``SMC_GET_GP(handle, ref)`` function,
+ supplying the appropriate ``CTX_GPREG_Xn`` reference, e.g.
+
+ .. code:: c
+
+ uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+
+#. Implementing the standard SMC32 Functions that provide information about
+ the implementation of the service. These are the Call Count, Implementor
+ UID and Revision Details for each service documented in section 6 of the
+ `SMCCC`_.
+
+ TF-A expects owning entities to follow this recommendation.
+
+#. Returning the result to the caller. The `SMCCC`_ allows for up to 256 bits
+ of return value in SMC64 using X0-X3 and 128 bits in SMC32 using W0-W3. The
+ framework provides a family of macros to set the multi-register return
+ value and complete the handler:
+
+ .. code:: c
+
+ SMC_RET1(handle, x0);
+ SMC_RET2(handle, x0, x1);
+ SMC_RET3(handle, x0, x1, x2);
+ SMC_RET4(handle, x0, x1, x2, x3);
+
+The ``cookie`` parameter to the handler is reserved for future use and can be
+ignored. The ``handle`` is returned by the SMC handler - completion of the
+handler function must always be via one of the ``SMC_RETn()`` macros.
+
+NOTE: The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow
+all of the above requirements yet.
+
+Services that contain multiple sub-services
+-------------------------------------------
+
+It is possible that a single owning entity implements multiple sub-services. For
+example, the Standard calls service handles ``0x84000000``-``0x8400FFFF`` and
+``0xC4000000``-``0xC400FFFF`` functions. Within that range, the `PSCI`_ service
+handles the ``0x84000000``-``0x8400001F`` and ``0xC4000000``-``0xC400001F`` functions.
+In that respect, `PSCI`_ is a 'sub-service' of the Standard calls service. In
+future, there could be additional such sub-services in the Standard calls
+service which perform independent functions.
+
+In this situation it may be valuable to introduce a second level framework to
+enable independent implementation of sub-services. Such a framework might look
+very similar to the current runtime services framework, but using a different
+part of the SMC Function ID to identify the sub-service. TF-A does not provide
+such a framework at present.
+
+Secure-EL1 Payload Dispatcher service (SPD)
+-------------------------------------------
+
+Services that handle SMC Functions targeting a Trusted OS, Trusted Application,
+or other Secure-EL1 Payload are special. These services need to manage the
+Secure-EL1 context, provide the *Secure Monitor* functionality of switching
+between the normal and secure worlds, deliver SMC Calls through to Secure-EL1
+and generally manage the Secure-EL1 Payload through CPU power-state transitions.
+
+TODO: Provide details of the additional work required to implement a SPD and
+the BL31 support for these services. Or a reference to the document that will
+provide this information....
+
+--------------
+
+*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
+.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
+.. _Firmware Design: ../designb_documents/firmware-design.rst
+.. _services: ../../services
+.. _lib/psci: ../../lib/psci
+.. _runtime_svc.h: ../../include/common/runtime_svc.h
+.. _smccc.h: ../../include/lib/smccc.h
+.. _std_svc_setup.c: ../../services/std_svc/std_svc_setup.c
--- /dev/null
+Trusted Firmware-A User Guide
+=============================
+
+
+
+
+.. contents::
+
+This document describes how to build Trusted Firmware-A (TF-A) and run it with a
+tested set of other software components using defined configurations on the Juno
+Arm development platform and Arm Fixed Virtual Platform (FVP) models. It is
+possible to use other software components, configurations and platforms but that
+is outside the scope of this document.
+
+This document assumes that the reader has previous experience running a fully
+bootable Linux software stack on Juno or FVP using the prebuilt binaries and
+filesystems provided by `Linaro`_. Further information may be found in the
+`Linaro instructions`_. It also assumes that the user understands the role of
+the different software components required to boot a Linux system:
+
+- Specific firmware images required by the platform (e.g. SCP firmware on Juno)
+- Normal world bootloader (e.g. UEFI or U-Boot)
+- Device tree
+- Linux kernel image
+- Root filesystem
+
+This document also assumes that the user is familiar with the `FVP models`_ and
+the different command line options available to launch the model.
+
+This document should be used in conjunction with the `Firmware Design`_.
+
+Host machine requirements
+-------------------------
+
+The minimum recommended machine specification for building the software and
+running the FVP models is a dual-core processor running at 2GHz with 12GB of
+RAM. For best performance, use a machine with a quad-core processor running at
+2.6GHz with 16GB of RAM.
+
+The software has been tested on Ubuntu 16.04 LTS (64-bit). Packages used for
+building the software were installed from that distribution unless otherwise
+specified.
+
+The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
+Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
+
+Tools
+-----
+
+Install the required packages to build TF-A with the following command:
+
+::
+
+ sudo apt-get install device-tree-compiler build-essential gcc make git libssl-dev
+
+TF-A has been tested with Linaro Release 18.04.
+
+Download and install the AArch32 or AArch64 little-endian GCC cross compiler. If
+you would like to use the latest features available, download GCC 8.2-2019.01
+compiler from `arm Developer page`_. Otherwise, the `Linaro Release Notes`_
+documents which version of the compiler to use for a given Linaro Release. Also,
+these `Linaro instructions`_ provide further guidance and a script, which can be
+used to download Linaro deliverables automatically.
+
+Optionally, TF-A can be built using clang version 4.0 or newer or Arm
+Compiler 6. See instructions below on how to switch the default compiler.
+
+In addition, the following optional packages and tools may be needed:
+
+- ``device-tree-compiler`` (dtc) package if you need to rebuild the Flattened Device
+ Tree (FDT) source files (``.dts`` files) provided with this software. The
+ version of dtc must be 1.4.6 or above.
+
+- For debugging, Arm `Development Studio 5 (DS-5)`_.
+
+- To create and modify the diagram files included in the documentation, `Dia`_.
+ This tool can be found in most Linux distributions. Inkscape is needed to
+ generate the actual \*.png files.
+
+Getting the TF-A source code
+----------------------------
+
+Clone the repository from the Gerrit server. The project details may be found
+on the `arm-trusted-firmware-a project page`_. We recommend the "`Clone with
+commit-msg hook`" clone method, which will setup the git commit hook that
+automatically generates and inserts appropriate `Change-Id:` lines in your
+commit messages.
+
+Checking source code style
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Trusted Firmware follows the `Linux Coding Style`_ . When making changes to the
+source, for submission to the project, the source must be in compliance with
+this style guide.
+
+Additional, project-specific guidelines are defined in the `Trusted Firmware-A
+Coding Guidelines`_ document.
+
+To assist with coding style compliance, the project Makefile contains two
+targets which both utilise the `checkpatch.pl` script that ships with the Linux
+source tree. The project also defines certain *checkpatch* options in the
+``.checkpatch.conf`` file in the top-level directory.
+
+**Note:** Checkpatch errors will gate upstream merging of pull requests.
+Checkpatch warnings will not gate merging but should be reviewed and fixed if
+possible.
+
+To check the entire source tree, you must first download copies of
+``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
+in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
+environment variable to point to ``checkpatch.pl`` (with the other 2 files in
+the same directory) and build the `checkcodebase` target:
+
+::
+
+ make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
+
+To just check the style on the files that differ between your local branch and
+the remote master, use:
+
+::
+
+ make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
+
+If you wish to check your patch against something other than the remote master,
+set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
+is set to ``origin/master``.
+
+Building TF-A
+-------------
+
+- Before building TF-A, the environment variable ``CROSS_COMPILE`` must point
+ to the Linaro cross compiler.
+
+ For AArch64:
+
+ ::
+
+ export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+
+ For AArch32:
+
+ ::
+
+ export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
+
+ It is possible to build TF-A using Clang or Arm Compiler 6. To do so
+ ``CC`` needs to point to the clang or armclang binary, which will
+ also select the clang or armclang assembler. Be aware that the
+ GNU linker is used by default. In case of being needed the linker
+ can be overridden using the ``LD`` variable. Clang linker version 6 is
+ known to work with TF-A.
+
+ In both cases ``CROSS_COMPILE`` should be set as described above.
+
+ Arm Compiler 6 will be selected when the base name of the path assigned
+ to ``CC`` matches the string 'armclang'.
+
+ For AArch64 using Arm Compiler 6:
+
+ ::
+
+ export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+ make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
+
+ Clang will be selected when the base name of the path assigned to ``CC``
+ contains the string 'clang'. This is to allow both clang and clang-X.Y
+ to work.
+
+ For AArch64 using clang:
+
+ ::
+
+ export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+ make CC=<path-to-clang>/bin/clang PLAT=<platform> all
+
+- Change to the root directory of the TF-A source tree and build.
+
+ For AArch64:
+
+ ::
+
+ make PLAT=<platform> all
+
+ For AArch32:
+
+ ::
+
+ make PLAT=<platform> ARCH=aarch32 AARCH32_SP=sp_min all
+
+ Notes:
+
+ - If ``PLAT`` is not specified, ``fvp`` is assumed by default. See the
+ `Summary of build options`_ for more information on available build
+ options.
+
+ - (AArch32 only) Currently only ``PLAT=fvp`` is supported.
+
+ - (AArch32 only) ``AARCH32_SP`` is the AArch32 EL3 Runtime Software and it
+ corresponds to the BL32 image. A minimal ``AARCH32_SP``, sp_min, is
+ provided by TF-A to demonstrate how PSCI Library can be integrated with
+ an AArch32 EL3 Runtime Software. Some AArch32 EL3 Runtime Software may
+ include other runtime services, for example Trusted OS services. A guide
+ to integrate PSCI library with AArch32 EL3 Runtime Software can be found
+ `here`_.
+
+ - (AArch64 only) The TSP (Test Secure Payload), corresponding to the BL32
+ image, is not compiled in by default. Refer to the
+ `Building the Test Secure Payload`_ section below.
+
+ - By default this produces a release version of the build. To produce a
+ debug version instead, refer to the "Debugging options" section below.
+
+ - The build process creates products in a ``build`` directory tree, building
+ the objects and binaries for each boot loader stage in separate
+ sub-directories. The following boot loader binary files are created
+ from the corresponding ELF files:
+
+ - ``build/<platform>/<build-type>/bl1.bin``
+ - ``build/<platform>/<build-type>/bl2.bin``
+ - ``build/<platform>/<build-type>/bl31.bin`` (AArch64 only)
+ - ``build/<platform>/<build-type>/bl32.bin`` (mandatory for AArch32)
+
+ where ``<platform>`` is the name of the chosen platform and ``<build-type>``
+ is either ``debug`` or ``release``. The actual number of images might differ
+ depending on the platform.
+
+- Build products for a specific build variant can be removed using:
+
+ ::
+
+ make DEBUG=<D> PLAT=<platform> clean
+
+ ... where ``<D>`` is ``0`` or ``1``, as specified when building.
+
+ The build tree can be removed completely using:
+
+ ::
+
+ make realclean
+
+Summary of build options
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The TF-A build system supports the following build options. Unless mentioned
+otherwise, these options are expected to be specified at the build command
+line and are not to be modified in any component makefiles. Note that the
+build system doesn't track dependency for build options. Therefore, if any of
+the build options are changed from a previous build, a clean build must be
+performed.
+
+Common build options
+^^^^^^^^^^^^^^^^^^^^
+
+- ``AARCH32_INSTRUCTION_SET``: Choose the AArch32 instruction set that the
+ compiler should use. Valid values are T32 and A32. It defaults to T32 due to
+ code having a smaller resulting size.
+
+- ``AARCH32_SP`` : Choose the AArch32 Secure Payload component to be built as
+ as the BL32 image when ``ARCH=aarch32``. The value should be the path to the
+ directory containing the SP source, relative to the ``bl32/``; the directory
+ is expected to contain a makefile called ``<aarch32_sp-value>.mk``.
+
+- ``ARCH`` : Choose the target build architecture for TF-A. It can take either
+ ``aarch64`` or ``aarch32`` as values. By default, it is defined to
+ ``aarch64``.
+
+- ``ARM_ARCH_MAJOR``: The major version of Arm Architecture to target when
+ compiling TF-A. Its value must be numeric, and defaults to 8 . See also,
+ *Armv8 Architecture Extensions* and *Armv7 Architecture Extensions* in
+ `Firmware Design`_.
+
+- ``ARM_ARCH_MINOR``: The minor version of Arm Architecture to target when
+ compiling TF-A. Its value must be a numeric, and defaults to 0. See also,
+ *Armv8 Architecture Extensions* in `Firmware Design`_.
+
+- ``BL2``: This is an optional build option which specifies the path to BL2
+ image for the ``fip`` target. In this case, the BL2 in the TF-A will not be
+ built.
+
+- ``BL2U``: This is an optional build option which specifies the path to
+ BL2U image. In this case, the BL2U in TF-A will not be built.
+
+- ``BL2_AT_EL3``: This is an optional build option that enables the use of
+ BL2 at EL3 execution level.
+
+- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
+ (XIP) memory, like BL1. In these use-cases, it is necessary to initialize
+ the RW sections in RAM, while leaving the RO sections in place. This option
+ enable this use-case. For now, this option is only supported when BL2_AT_EL3
+ is set to '1'.
+
+- ``BL31``: This is an optional build option which specifies the path to
+ BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
+ be built.
+
+- ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+ file that contains the BL31 private key in PEM format. If ``SAVE_KEYS=1``,
+ this file name will be used to save the key.
+
+- ``BL32``: This is an optional build option which specifies the path to
+ BL32 image for the ``fip`` target. In this case, the BL32 in TF-A will not
+ be built.
+
+- ``BL32_EXTRA1``: This is an optional build option which specifies the path to
+ Trusted OS Extra1 image for the ``fip`` target.
+
+- ``BL32_EXTRA2``: This is an optional build option which specifies the path to
+ Trusted OS Extra2 image for the ``fip`` target.
+
+- ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+ file that contains the BL32 private key in PEM format. If ``SAVE_KEYS=1``,
+ this file name will be used to save the key.
+
+- ``BL33``: Path to BL33 image in the host file system. This is mandatory for
+ ``fip`` target in case TF-A BL2 is used.
+
+- ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+ file that contains the BL33 private key in PEM format. If ``SAVE_KEYS=1``,
+ this file name will be used to save the key.
+
+- ``BUILD_MESSAGE_TIMESTAMP``: String used to identify the time and date of the
+ compilation of each build. It must be set to a C string (including quotes
+ where applicable). Defaults to a string that contains the time and date of
+ the compilation.
+
+- ``BUILD_STRING``: Input string for VERSION_STRING, which allows the TF-A
+ build to be uniquely identified. Defaults to the current git commit id.
+
+- ``CFLAGS``: Extra user options appended on the compiler's command line in
+ addition to the options set by the build system.
+
+- ``COLD_BOOT_SINGLE_CPU``: This option indicates whether the platform may
+ release several CPUs out of reset. It can take either 0 (several CPUs may be
+ brought up) or 1 (only one CPU will ever be brought up during cold reset).
+ Default is 0. If the platform always brings up a single CPU, there is no
+ need to distinguish between primary and secondary CPUs and the boot path can
+ be optimised. The ``plat_is_my_cpu_primary()`` and
+ ``plat_secondary_cold_boot_setup()`` platform porting interfaces do not need
+ to be implemented in this case.
+
+- ``CRASH_REPORTING``: A non-zero value enables a console dump of processor
+ register state when an unexpected exception occurs during execution of
+ BL31. This option defaults to the value of ``DEBUG`` - i.e. by default
+ this is only enabled for a debug build of the firmware.
+
+- ``CREATE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
+ certificate generation tool to create new keys in case no valid keys are
+ present or specified. Allowed options are '0' or '1'. Default is '1'.
+
+- ``CTX_INCLUDE_AARCH32_REGS`` : Boolean option that, when set to 1, will cause
+ the AArch32 system registers to be included when saving and restoring the
+ CPU context. The option must be set to 0 for AArch64-only platforms (that
+ is on hardware that does not implement AArch32, or at least not at EL1 and
+ higher ELs). Default value is 1.
+
+- ``CTX_INCLUDE_FPREGS``: Boolean option that, when set to 1, will cause the FP
+ registers to be included when saving and restoring the CPU context. Default
+ is 0.
+
+- ``CTX_INCLUDE_PAUTH_REGS``: Boolean option that, when set to 1, allows
+ Pointer Authentication for **Secure world**. This will cause the
+ Armv8.3-PAuth registers to be included when saving and restoring the CPU
+ context as part of a world switch. Default value is 0. Pointer Authentication
+ is an experimental feature.
+
+ Note that, if the CPU supports it, Pointer Authentication is allowed for
+ Non-secure world irrespectively of the value of this flag. "Allowed" means
+ that accesses to PAuth-related registers or execution of PAuth-related
+ instructions will not be trapped to EL3. As such, usage or not of PAuth in
+ Non-secure world images, depends on those images themselves.
+
+- ``DEBUG``: Chooses between a debug and release build. It can take either 0
+ (release) or 1 (debug) as values. 0 is the default.
+
+- ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation
+ of the binary image. If set to 1, then only the ELF image is built.
+ 0 is the default.
+
+- ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted
+ Board Boot authentication at runtime. This option is meant to be enabled only
+ for development platforms. ``TRUSTED_BOARD_BOOT`` flag must be set if this
+ flag has to be enabled. 0 is the default.
+
+- ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of
+ the normal boot flow. It must specify the entry point address of the EL3
+ payload. Please refer to the "Booting an EL3 payload" section for more
+ details.
+
+- ``ENABLE_AMU``: Boolean option to enable Activity Monitor Unit extensions.
+ This is an optional architectural feature available on v8.4 onwards. Some
+ v8.2 implementations also implement an AMU and this option can be used to
+ enable this feature on those systems as well. Default is 0.
+
+- ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()``
+ are compiled out. For debug builds, this option defaults to 1, and calls to
+ ``assert()`` are left in place. For release builds, this option defaults to 0
+ and calls to ``assert()`` function are compiled out. This option can be set
+ independently of ``DEBUG``. It can also be used to hide any auxiliary code
+ that is only required for the assertion and does not fit in the assertion
+ itself.
+
+- ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace
+ dumps or not. It is supported in both AArch64 and AArch32. However, in
+ AArch32 the format of the frame records are not defined in the AAPCS and they
+ are defined by the implementation. This implementation of backtrace only
+ supports the format used by GCC when T32 interworking is disabled. For this
+ reason enabling this option in AArch32 will force the compiler to only
+ generate A32 code. This option is enabled by default only in AArch64 debug
+ builds, but this behaviour can be overridden in each platform's Makefile or
+ in the build command line.
+
+- ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
+ feature. MPAM is an optional Armv8.4 extension that enables various memory
+ system components and resources to define partitions; software running at
+ various ELs can assign themselves to desired partition to control their
+ performance aspects.
+
+ When this option is set to ``1``, EL3 allows lower ELs to access their own
+ MPAM registers without trapping into EL3. This option doesn't make use of
+ partitioning in EL3, however. Platform initialisation code should configure
+ and use partitions in EL3 as required. This option defaults to ``0``.
+
+- ``ENABLE_PAUTH``: Boolean option to enable Armv8.3 Pointer Authentication
+ for **TF-A BL images themselves**. If enabled, the compiler must support the
+ ``-msign-return-address`` option. This flag defaults to 0. Pointer
+ Authentication is an experimental feature.
+
+ If this flag is enabled, ``CTX_INCLUDE_PAUTH_REGS`` must also be enabled.
+
+- ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE)
+ support within generic code in TF-A. This option is currently only supported
+ in BL31. Default is 0.
+
+- ``ENABLE_PMF``: Boolean option to enable support for optional Performance
+ Measurement Framework(PMF). Default is 0.
+
+- ``ENABLE_PSCI_STAT``: Boolean option to enable support for optional PSCI
+ functions ``PSCI_STAT_RESIDENCY`` and ``PSCI_STAT_COUNT``. Default is 0.
+ In the absence of an alternate stat collection backend, ``ENABLE_PMF`` must
+ be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in
+ software.
+
+- ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime
+ instrumentation which injects timestamp collection points into TF-A to
+ allow runtime performance to be measured. Currently, only PSCI is
+ instrumented. Enabling this option enables the ``ENABLE_PMF`` build option
+ as well. Default is 0.
+
+- ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
+ extensions. This is an optional architectural feature for AArch64.
+ The default is 1 but is automatically disabled when the target architecture
+ is AArch32.
+
+- ``ENABLE_SPM`` : Boolean option to enable the Secure Partition Manager (SPM).
+ Refer to the `Secure Partition Manager Design guide`_ for more details about
+ this feature. Default is 0.
+
+- ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension
+ (SVE) for the Non-secure world only. SVE is an optional architectural feature
+ for AArch64. Note that when SVE is enabled for the Non-secure world, access
+ to SIMD and floating-point functionality from the Secure world is disabled.
+ This is to avoid corruption of the Non-secure world data in the Z-registers
+ which are aliased by the SIMD and FP registers. The build option is not
+ compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
+ assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to
+ 1. The default is 1 but is automatically disabled when the target
+ architecture is AArch32.
+
+- ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
+ checks in GCC. Allowed values are "all", "strong", "default" and "none". The
+ default value is set to "none". "strong" is the recommended stack protection
+ level if this feature is desired. "none" disables the stack protection. For
+ all values other than "none", the ``plat_get_stack_protector_canary()``
+ platform hook needs to be implemented. The value is passed as the last
+ component of the option ``-fstack-protector-$ENABLE_STACK_PROTECTOR``.
+
+- ``ERROR_DEPRECATED``: This option decides whether to treat the usage of
+ deprecated platform APIs, helper functions or drivers within Trusted
+ Firmware as error. It can take the value 1 (flag the use of deprecated
+ APIs as error) or 0. The default is 0.
+
+- ``EL3_EXCEPTION_HANDLING``: When set to ``1``, enable handling of exceptions
+ targeted at EL3. When set ``0`` (default), no exceptions are expected or
+ handled at EL3, and a panic will result. This is supported only for AArch64
+ builds.
+
+- ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault
+ injection from lower ELs, and this build option enables lower ELs to use
+ Error Records accessed via System Registers to inject faults. This is
+ applicable only to AArch64 builds.
+
+ This feature is intended for testing purposes only, and is advisable to keep
+ disabled for production images.
+
+- ``FIP_NAME``: This is an optional build option which specifies the FIP
+ filename for the ``fip`` target. Default is ``fip.bin``.
+
+- ``FWU_FIP_NAME``: This is an optional build option which specifies the FWU
+ FIP filename for the ``fwu_fip`` target. Default is ``fwu_fip.bin``.
+
+- ``GENERATE_COT``: Boolean flag used to build and execute the ``cert_create``
+ tool to create certificates as per the Chain of Trust described in
+ `Trusted Board Boot`_. The build system then calls ``fiptool`` to
+ include the certificates in the FIP and FWU_FIP. Default value is '0'.
+
+ Specify both ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=1`` to include support
+ for the Trusted Board Boot feature in the BL1 and BL2 images, to generate
+ the corresponding certificates, and to include those certificates in the
+ FIP and FWU_FIP.
+
+ Note that if ``TRUSTED_BOARD_BOOT=0`` and ``GENERATE_COT=1``, the BL1 and BL2
+ images will not include support for Trusted Board Boot. The FIP will still
+ include the corresponding certificates. This FIP can be used to verify the
+ Chain of Trust on the host machine through other mechanisms.
+
+ Note that if ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=0``, the BL1 and BL2
+ images will include support for Trusted Board Boot, but the FIP and FWU_FIP
+ will not include the corresponding certificates, causing a boot failure.
+
+- ``GICV2_G0_FOR_EL3``: Unlike GICv3, the GICv2 architecture doesn't have
+ inherent support for specific EL3 type interrupts. Setting this build option
+ to ``1`` assumes GICv2 *Group 0* interrupts are expected to target EL3, both
+ by `platform abstraction layer`__ and `Interrupt Management Framework`__.
+ This allows GICv2 platforms to enable features requiring EL3 interrupt type.
+ This also means that all GICv2 Group 0 interrupts are delivered to EL3, and
+ the Secure Payload interrupts needs to be synchronously handed over to Secure
+ EL1 for handling. The default value of this option is ``0``, which means the
+ Group 0 interrupts are assumed to be handled by Secure EL1.
+
+ .. __: `platform-interrupt-controller-API.rst`
+ .. __: `interrupt-framework-design.rst`
+
+- ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError
+ Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to
+ ``0`` (default), these exceptions will be trapped in the current exception
+ level (or in EL1 if the current exception level is EL0).
+
+- ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific
+ software operations are required for CPUs to enter and exit coherency.
+ However, newer systems exist where CPUs' entry to and exit from coherency
+ is managed in hardware. Such systems require software to only initiate these
+ operations, and the rest is managed in hardware, minimizing active software
+ management. In such systems, this boolean option enables TF-A to carry out
+ build and run-time optimizations during boot and power management operations.
+ This option defaults to 0 and if it is enabled, then it implies
+ ``WARMBOOT_ENABLE_DCACHE_EARLY`` is also enabled.
+
+ If this flag is disabled while the platform which TF-A is compiled for
+ includes cores that manage coherency in hardware, then a compilation error is
+ generated. This is based on the fact that a system cannot have, at the same
+ time, cores that manage coherency in hardware and cores that don't. In other
+ words, a platform cannot have, at the same time, cores that require
+ ``HW_ASSISTED_COHERENCY=1`` and cores that require
+ ``HW_ASSISTED_COHERENCY=0``.
+
+ Note that, when ``HW_ASSISTED_COHERENCY`` is enabled, version 2 of
+ translation library (xlat tables v2) must be used; version 1 of translation
+ library is not supported.
+
+- ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
+ runtime software in AArch32 mode, which is required to run AArch32 on Juno.
+ By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
+ AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
+ images.
+
+- ``KEY_ALG``: This build flag enables the user to select the algorithm to be
+ used for generating the PKCS keys and subsequent signing of the certificate.
+ It accepts 3 values: ``rsa``, ``rsa_1_5`` and ``ecdsa``. The option
+ ``rsa_1_5`` is the legacy PKCS#1 RSA 1.5 algorithm which is not TBBR
+ compliant and is retained only for compatibility. The default value of this
+ flag is ``rsa`` which is the TBBR compliant PKCS#1 RSA 2.1 scheme.
+
+- ``HASH_ALG``: This build flag enables the user to select the secure hash
+ algorithm. It accepts 3 values: ``sha256``, ``sha384`` and ``sha512``.
+ The default value of this flag is ``sha256``.
+
+- ``LDFLAGS``: Extra user options appended to the linkers' command line in
+ addition to the one set by the build system.
+
+- ``LOG_LEVEL``: Chooses the log level, which controls the amount of console log
+ output compiled into the build. This should be one of the following:
+
+ ::
+
+ 0 (LOG_LEVEL_NONE)
+ 10 (LOG_LEVEL_ERROR)
+ 20 (LOG_LEVEL_NOTICE)
+ 30 (LOG_LEVEL_WARNING)
+ 40 (LOG_LEVEL_INFO)
+ 50 (LOG_LEVEL_VERBOSE)
+
+ All log output up to and including the selected log level is compiled into
+ the build. The default value is 40 in debug builds and 20 in release builds.
+
+- ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
+ specifies the file that contains the Non-Trusted World private key in PEM
+ format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
+
+- ``NS_BL2U``: Path to NS_BL2U image in the host file system. This image is
+ optional. It is only needed if the platform makefile specifies that it
+ is required in order to build the ``fwu_fip`` target.
+
+- ``NS_TIMER_SWITCH``: Enable save and restore for non-secure timer register
+ contents upon world switch. It can take either 0 (don't save and restore) or
+ 1 (do save and restore). 0 is the default. An SPD may set this to 1 if it
+ wants the timer registers to be saved and restored.
+
+- ``OVERRIDE_LIBC``: This option allows platforms to override the default libc
+ for the BL image. It can be either 0 (include) or 1 (remove). The default
+ value is 0.
+
+- ``PL011_GENERIC_UART``: Boolean option to indicate the PL011 driver that
+ the underlying hardware is not a full PL011 UART but a minimally compliant
+ generic UART, which is a subset of the PL011. The driver will not access
+ any register that is not part of the SBSA generic UART specification.
+ Default value is 0 (a full PL011 compliant UART is present).
+
+- ``PLAT``: Choose a platform to build TF-A for. The chosen platform name
+ must be subdirectory of any depth under ``plat/``, and must contain a
+ platform makefile named ``platform.mk``. For example, to build TF-A for the
+ Arm Juno board, select PLAT=juno.
+
+- ``PRELOADED_BL33_BASE``: This option enables booting a preloaded BL33 image
+ instead of the normal boot flow. When defined, it must specify the entry
+ point address for the preloaded BL33 image. This option is incompatible with
+ ``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority
+ over ``PRELOADED_BL33_BASE``.
+
+- ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset
+ vector address can be programmed or is fixed on the platform. It can take
+ either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a
+ programmable reset address, it is expected that a CPU will start executing
+ code directly at the right address, both on a cold and warm reset. In this
+ case, there is no need to identify the entrypoint on boot and the boot path
+ can be optimised. The ``plat_get_my_entrypoint()`` platform porting interface
+ does not need to be implemented in this case.
+
+- ``PSCI_EXTENDED_STATE_ID``: As per PSCI1.0 Specification, there are 2 formats
+ possible for the PSCI power-state parameter: original and extended State-ID
+ formats. This flag if set to 1, configures the generic PSCI layer to use the
+ extended format. The default value of this flag is 0, which means by default
+ the original power-state format is used by the PSCI implementation. This flag
+ should be specified by the platform makefile and it governs the return value
+ of PSCI_FEATURES API for CPU_SUSPEND smc function id. When this option is
+ enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be
+ set to 1 as well.
+
+- ``RAS_EXTENSION``: When set to ``1``, enable Armv8.2 RAS features. RAS features
+ are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
+ or later CPUs.
+
+ When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be
+ set to ``1``.
+
+ This option is disabled by default.
+
+- ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead
+ of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
+ entrypoint) or 1 (CPU reset to BL31 entrypoint).
+ The default value is 0.
+
+- ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided
+ in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector
+ instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
+ entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
+
+- ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+ file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this
+ file name will be used to save the key.
+
+- ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
+ certificate generation tool to save the keys used to establish the Chain of
+ Trust. Allowed options are '0' or '1'. Default is '0' (do not save).
+
+- ``SCP_BL2``: Path to SCP_BL2 image in the host file system. This image is optional.
+ If a SCP_BL2 image is present then this option must be passed for the ``fip``
+ target.
+
+- ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
+ file that contains the SCP_BL2 private key in PEM format. If ``SAVE_KEYS=1``,
+ this file name will be used to save the key.
+
+- ``SCP_BL2U``: Path to SCP_BL2U image in the host file system. This image is
+ optional. It is only needed if the platform makefile specifies that it
+ is required in order to build the ``fwu_fip`` target.
+
+- ``SDEI_SUPPORT``: Setting this to ``1`` enables support for Software
+ Delegated Exception Interface to BL31 image. This defaults to ``0``.
+
+ When set to ``1``, the build option ``EL3_EXCEPTION_HANDLING`` must also be
+ set to ``1``.
+
+- ``SEPARATE_CODE_AND_RODATA``: Whether code and read-only data should be
+ isolated on separate memory pages. This is a trade-off between security and
+ memory usage. See "Isolating code and read-only data on separate memory
+ pages" section in `Firmware Design`_. This flag is disabled by default and
+ affects all BL images.
+
+- ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A.
+ This build option is only valid if ``ARCH=aarch64``. The value should be
+ the path to the directory containing the SPD source, relative to
+ ``services/spd/``; the directory is expected to contain a makefile called
+ ``<spd-value>.mk``.
+
+- ``SPIN_ON_BL1_EXIT``: This option introduces an infinite loop in BL1. It can
+ take either 0 (no loop) or 1 (add a loop). 0 is the default. This loop stops
+ execution in BL1 just before handing over to BL31. At this point, all
+ firmware images have been loaded in memory, and the MMU and caches are
+ turned off. Refer to the "Debugging options" section for more details.
+
+- ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
+ secure interrupts (caught through the FIQ line). Platforms can enable
+ this directive if they need to handle such interruption. When enabled,
+ the FIQ are handled in monitor mode and non secure world is not allowed
+ to mask these events. Platforms that enable FIQ handling in SP_MIN shall
+ implement the api ``sp_min_plat_fiq_handler()``. The default value is 0.
+
+- ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board
+ Boot feature. When set to '1', BL1 and BL2 images include support to load
+ and verify the certificates and images in a FIP, and BL1 includes support
+ for the Firmware Update. The default value is '0'. Generation and inclusion
+ of certificates in the FIP and FWU_FIP depends upon the value of the
+ ``GENERATE_COT`` option.
+
+ Note: This option depends on ``CREATE_KEYS`` to be enabled. If the keys
+ already exist in disk, they will be overwritten without further notice.
+
+- ``TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
+ specifies the file that contains the Trusted World private key in PEM
+ format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
+
+- ``TSP_INIT_ASYNC``: Choose BL32 initialization method as asynchronous or
+ synchronous, (see "Initializing a BL32 Image" section in
+ `Firmware Design`_). It can take the value 0 (BL32 is initialized using
+ synchronous method) or 1 (BL32 is initialized using asynchronous method).
+ Default is 0.
+
+- ``TSP_NS_INTR_ASYNC_PREEMPT``: A non zero value enables the interrupt
+ routing model which routes non-secure interrupts asynchronously from TSP
+ to EL3 causing immediate preemption of TSP. The EL3 is responsible
+ for saving and restoring the TSP context in this routing model. The
+ default routing model (when the value is 0) is to route non-secure
+ interrupts to TSP allowing it to save its context and hand over
+ synchronously to EL3 via an SMC.
+
+ Note: when ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
+ must also be set to ``1``.
+
+- ``USE_ARM_LINK``: This flag determines whether to enable support for ARM
+ linker. When the ``LINKER`` build variable points to the armlink linker,
+ this flag is enabled automatically. To enable support for armlink, platforms
+ will have to provide a scatter file for the BL image. Currently, Tegra
+ platforms use the armlink support to compile BL3-1 images.
+
+- ``USE_COHERENT_MEM``: This flag determines whether to include the coherent
+ memory region in the BL memory map or not (see "Use of Coherent memory in
+ TF-A" section in `Firmware Design`_). It can take the value 1
+ (Coherent memory region is included) or 0 (Coherent memory region is
+ excluded). Default is 1.
+
+- ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
+ This feature creates a library of functions to be placed in ROM and thus
+ reduces SRAM usage. Refer to `Library at ROM`_ for further details. Default
+ is 0.
+
+- ``V``: Verbose build. If assigned anything other than 0, the build commands
+ are printed. Default is 0.
+
+- ``VERSION_STRING``: String used in the log output for each TF-A image.
+ Defaults to a string formed by concatenating the version number, build type
+ and build string.
+
+- ``WARMBOOT_ENABLE_DCACHE_EARLY`` : Boolean option to enable D-cache early on
+ the CPU after warm boot. This is applicable for platforms which do not
+ require interconnect programming to enable cache coherency (eg: single
+ cluster platforms). If this option is enabled, then warm boot path
+ enables D-caches immediately after enabling MMU. This option defaults to 0.
+
+Arm development platform specific build options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``ARM_BL31_IN_DRAM``: Boolean option to select loading of BL31 in TZC secured
+ DRAM. By default, BL31 is in the secure SRAM. Set this flag to 1 to load
+ BL31 in TZC secured DRAM. If TSP is present, then setting this option also
+ sets the TSP location to DRAM and ignores the ``ARM_TSP_RAM_LOCATION`` build
+ flag.
+
+- ``ARM_CONFIG_CNTACR``: boolean option to unlock access to the ``CNTBase<N>``
+ frame registers by setting the ``CNTCTLBase.CNTACR<N>`` register bits. The
+ frame number ``<N>`` is defined by ``PLAT_ARM_NSTIMER_FRAME_ID``, which should
+ match the frame used by the Non-Secure image (normally the Linux kernel).
+ Default is true (access to the frame is allowed).
+
+- ``ARM_DISABLE_TRUSTED_WDOG``: boolean option to disable the Trusted Watchdog.
+ By default, Arm platforms use a watchdog to trigger a system reset in case
+ an error is encountered during the boot process (for example, when an image
+ could not be loaded or authenticated). The watchdog is enabled in the early
+ platform setup hook at BL1 and disabled in the BL1 prepare exit hook. The
+ Trusted Watchdog may be disabled at build time for testing or development
+ purposes.
+
+- ``ARM_LINUX_KERNEL_AS_BL33``: The Linux kernel expects registers x0-x3 to
+ have specific values at boot. This boolean option allows the Trusted Firmware
+ to have a Linux kernel image as BL33 by preparing the registers to these
+ values before jumping to BL33. This option defaults to 0 (disabled). For
+ AArch64 ``RESET_TO_BL31`` and for AArch32 ``RESET_TO_SP_MIN`` must be 1 when
+ using it. If this option is set to 1, ``ARM_PRELOADED_DTB_BASE`` must be set
+ to the location of a device tree blob (DTB) already loaded in memory. The
+ Linux Image address must be specified using the ``PRELOADED_BL33_BASE``
+ option.
+
+- ``ARM_PLAT_MT``: This flag determines whether the Arm platform layer has to
+ cater for the multi-threading ``MT`` bit when accessing MPIDR. When this flag
+ is set, the functions which deal with MPIDR assume that the ``MT`` bit in
+ MPIDR is set and access the bit-fields in MPIDR accordingly. Default value of
+ this flag is 0. Note that this option is not used on FVP platforms.
+
+- ``ARM_RECOM_STATE_ID_ENC``: The PSCI1.0 specification recommends an encoding
+ for the construction of composite state-ID in the power-state parameter.
+ The existing PSCI clients currently do not support this encoding of
+ State-ID yet. Hence this flag is used to configure whether to use the
+ recommended State-ID encoding or not. The default value of this flag is 0,
+ in which case the platform is configured to expect NULL in the State-ID
+ field of power-state parameter.
+
+- ``ARM_ROTPK_LOCATION``: used when ``TRUSTED_BOARD_BOOT=1``. It specifies the
+ location of the ROTPK hash returned by the function ``plat_get_rotpk_info()``
+ for Arm platforms. Depending on the selected option, the proper private key
+ must be specified using the ``ROT_KEY`` option when building the Trusted
+ Firmware. This private key will be used by the certificate generation tool
+ to sign the BL2 and Trusted Key certificates. Available options for
+ ``ARM_ROTPK_LOCATION`` are:
+
+ - ``regs`` : return the ROTPK hash stored in the Trusted root-key storage
+ registers. The private key corresponding to this ROTPK hash is not
+ currently available.
+ - ``devel_rsa`` : return a development public key hash embedded in the BL1
+ and BL2 binaries. This hash has been obtained from the RSA public key
+ ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use
+ this option, ``arm_rotprivk_rsa.pem`` must be specified as ``ROT_KEY`` when
+ creating the certificates.
+ - ``devel_ecdsa`` : return a development public key hash embedded in the BL1
+ and BL2 binaries. This hash has been obtained from the ECDSA public key
+ ``arm_rotpk_ecdsa.der``, located in ``plat/arm/board/common/rotpk``. To use
+ this option, ``arm_rotprivk_ecdsa.pem`` must be specified as ``ROT_KEY``
+ when creating the certificates.
+
+- ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
+
+ - ``tsram`` : Trusted SRAM (default option when TBB is not enabled)
+ - ``tdram`` : Trusted DRAM (if available)
+ - ``dram`` : Secure region in DRAM (default option when TBB is enabled,
+ configured by the TrustZone controller)
+
+- ``ARM_XLAT_TABLES_LIB_V1``: boolean option to compile TF-A with version 1
+ of the translation tables library instead of version 2. It is set to 0 by
+ default, which selects version 2.
+
+- ``ARM_CRYPTOCELL_INTEG`` : bool option to enable TF-A to invoke Arm®
+ TrustZone® CryptoCell functionality for Trusted Board Boot on capable Arm
+ platforms. If this option is specified, then the path to the CryptoCell
+ SBROM library must be specified via ``CCSBROM_LIB_PATH`` flag.
+
+For a better understanding of these options, the Arm development platform memory
+map is explained in the `Firmware Design`_.
+
+Arm CSS platform specific build options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``CSS_DETECT_PRE_1_7_0_SCP``: Boolean flag to detect SCP version
+ incompatibility. Version 1.7.0 of the SCP firmware made a non-backwards
+ compatible change to the MTL protocol, used for AP/SCP communication.
+ TF-A no longer supports earlier SCP versions. If this option is set to 1
+ then TF-A will detect if an earlier version is in use. Default is 1.
+
+- ``CSS_LOAD_SCP_IMAGES``: Boolean flag, which when set, adds SCP_BL2 and
+ SCP_BL2U to the FIP and FWU_FIP respectively, and enables them to be loaded
+ during boot. Default is 1.
+
+- ``CSS_USE_SCMI_SDS_DRIVER``: Boolean flag which selects SCMI/SDS drivers
+ instead of SCPI/BOM driver for communicating with the SCP during power
+ management operations and for SCP RAM Firmware transfer. If this option
+ is set to 1, then SCMI/SDS drivers will be used. Default is 0.
+
+Arm FVP platform specific build options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``FVP_CLUSTER_COUNT`` : Configures the cluster count to be used to
+ build the topology tree within TF-A. By default TF-A is configured for dual
+ cluster topology and this option can be used to override the default value.
+
+- ``FVP_INTERCONNECT_DRIVER``: Selects the interconnect driver to be built. The
+ default interconnect driver depends on the value of ``FVP_CLUSTER_COUNT`` as
+ explained in the options below:
+
+ - ``FVP_CCI`` : The CCI driver is selected. This is the default
+ if 0 < ``FVP_CLUSTER_COUNT`` <= 2.
+ - ``FVP_CCN`` : The CCN driver is selected. This is the default
+ if ``FVP_CLUSTER_COUNT`` > 2.
+
+- ``FVP_MAX_CPUS_PER_CLUSTER``: Sets the maximum number of CPUs implemented in
+ a single cluster. This option defaults to 4.
+
+- ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
+ in the system. This option defaults to 1. Note that the build option
+ ``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
+
+- ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
+
+ - ``FVP_GIC600`` : The GIC600 implementation of GICv3 is selected
+ - ``FVP_GICV2`` : The GICv2 only driver is selected
+ - ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
+
+- ``FVP_USE_SP804_TIMER`` : Use the SP804 timer instead of the Generic Timer
+ for functions that wait for an arbitrary time length (udelay and mdelay).
+ The default value is 0.
+
+- ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
+ to DTB and packaged in FIP as the HW_CONFIG. See `Firmware Design`_ for
+ details on HW_CONFIG. By default, this is initialized to a sensible DTS
+ file in ``fdts/`` folder depending on other build options. But some cases,
+ like shifted affinity format for MPIDR, cannot be detected at build time
+ and this option is needed to specify the appropriate DTS file.
+
+- ``FVP_HW_CONFIG`` : Specify the path to the HW_CONFIG blob to be packaged in
+ FIP. See `Firmware Design`_ for details on HW_CONFIG. This option is
+ similar to the ``FVP_HW_CONFIG_DTS`` option, but it directly specifies the
+ HW_CONFIG blob instead of the DTS file. This option is useful to override
+ the default HW_CONFIG selected by the build system.
+
+ARM JUNO platform specific build options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- ``JUNO_TZMP1`` : Boolean option to configure Juno to be used for TrustZone
+ Media Protection (TZ-MP1). Default value of this flag is 0.
+
+Debugging options
+~~~~~~~~~~~~~~~~~
+
+To compile a debug version and make the build more verbose use
+
+::
+
+ make PLAT=<platform> DEBUG=1 V=1 all
+
+AArch64 GCC uses DWARF version 4 debugging symbols by default. Some tools (for
+example DS-5) might not support this and may need an older version of DWARF
+symbols to be emitted by GCC. This can be achieved by using the
+``-gdwarf-<version>`` flag, with the version being set to 2 or 3. Setting the
+version to 2 is recommended for DS-5 versions older than 5.16.
+
+When debugging logic problems it might also be useful to disable all compiler
+optimizations by using ``-O0``.
+
+NOTE: Using ``-O0`` could cause output images to be larger and base addresses
+might need to be recalculated (see the **Memory layout on Arm development
+platforms** section in the `Firmware Design`_).
+
+Extra debug options can be passed to the build system by setting ``CFLAGS`` or
+``LDFLAGS``:
+
+.. code:: makefile
+
+ CFLAGS='-O0 -gdwarf-2' \
+ make PLAT=<platform> DEBUG=1 V=1 all
+
+Note that using ``-Wl,`` style compilation driver options in ``CFLAGS`` will be
+ignored as the linker is called directly.
+
+It is also possible to introduce an infinite loop to help in debugging the
+post-BL2 phase of TF-A. This can be done by rebuilding BL1 with the
+``SPIN_ON_BL1_EXIT=1`` build flag. Refer to the `Summary of build options`_
+section. In this case, the developer may take control of the target using a
+debugger when indicated by the console output. When using DS-5, the following
+commands can be used:
+
+::
+
+ # Stop target execution
+ interrupt
+
+ #
+ # Prepare your debugging environment, e.g. set breakpoints
+ #
+
+ # Jump over the debug loop
+ set var $AARCH64::$Core::$PC = $AARCH64::$Core::$PC + 4
+
+ # Resume execution
+ continue
+
+Building the Test Secure Payload
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The TSP is coupled with a companion runtime service in the BL31 firmware,
+called the TSPD. Therefore, if you intend to use the TSP, the BL31 image
+must be recompiled as well. For more information on SPs and SPDs, see the
+`Secure-EL1 Payloads and Dispatchers`_ section in the `Firmware Design`_.
+
+First clean the TF-A build directory to get rid of any previous BL31 binary.
+Then to build the TSP image use:
+
+::
+
+ make PLAT=<platform> SPD=tspd all
+
+An additional boot loader binary file is created in the ``build`` directory:
+
+::
+
+ build/<platform>/<build-type>/bl32.bin
+
+
+Building and using the FIP tool
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Firmware Image Package (FIP) is a packaging format used by TF-A to package
+firmware images in a single binary. The number and type of images that should
+be packed in a FIP is platform specific and may include TF-A images and other
+firmware images required by the platform. For example, most platforms require
+a BL33 image which corresponds to the normal world bootloader (e.g. UEFI or
+U-Boot).
+
+The TF-A build system provides the make target ``fip`` to create a FIP file
+for the specified platform using the FIP creation tool included in the TF-A
+project. Examples below show how to build a FIP file for FVP, packaging TF-A
+and BL33 images.
+
+For AArch64:
+
+::
+
+ make PLAT=fvp BL33=<path-to>/bl33.bin fip
+
+For AArch32:
+
+::
+
+ make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=<path-to>/bl33.bin fip
+
+The resulting FIP may be found in:
+
+::
+
+ build/fvp/<build-type>/fip.bin
+
+For advanced operations on FIP files, it is also possible to independently build
+the tool and create or modify FIPs using this tool. To do this, follow these
+steps:
+
+It is recommended to remove old artifacts before building the tool:
+
+::
+
+ make -C tools/fiptool clean
+
+Build the tool:
+
+::
+
+ make [DEBUG=1] [V=1] fiptool
+
+The tool binary can be located in:
+
+::
+
+ ./tools/fiptool/fiptool
+
+Invoking the tool with ``help`` will print a help message with all available
+options.
+
+Example 1: create a new Firmware package ``fip.bin`` that contains BL2 and BL31:
+
+::
+
+ ./tools/fiptool/fiptool create \
+ --tb-fw build/<platform>/<build-type>/bl2.bin \
+ --soc-fw build/<platform>/<build-type>/bl31.bin \
+ fip.bin
+
+Example 2: view the contents of an existing Firmware package:
+
+::
+
+ ./tools/fiptool/fiptool info <path-to>/fip.bin
+
+Example 3: update the entries of an existing Firmware package:
+
+::
+
+ # Change the BL2 from Debug to Release version
+ ./tools/fiptool/fiptool update \
+ --tb-fw build/<platform>/release/bl2.bin \
+ build/<platform>/debug/fip.bin
+
+Example 4: unpack all entries from an existing Firmware package:
+
+::
+
+ # Images will be unpacked to the working directory
+ ./tools/fiptool/fiptool unpack <path-to>/fip.bin
+
+Example 5: remove an entry from an existing Firmware package:
+
+::
+
+ ./tools/fiptool/fiptool remove \
+ --tb-fw build/<platform>/debug/fip.bin
+
+Note that if the destination FIP file exists, the create, update and
+remove operations will automatically overwrite it.
+
+The unpack operation will fail if the images already exist at the
+destination. In that case, use -f or --force to continue.
+
+More information about FIP can be found in the `Firmware Design`_ document.
+
+Building FIP images with support for Trusted Board Boot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Trusted Board Boot primarily consists of the following two features:
+
+- Image Authentication, described in `Trusted Board Boot`_, and
+- Firmware Update, described in `Firmware Update`_
+
+The following steps should be followed to build FIP and (optionally) FWU_FIP
+images with support for these features:
+
+#. Fulfill the dependencies of the ``mbedtls`` cryptographic and image parser
+ modules by checking out a recent version of the `mbed TLS Repository`_. It
+ is important to use a version that is compatible with TF-A and fixes any
+ known security vulnerabilities. See `mbed TLS Security Center`_ for more
+ information. The latest version of TF-A is tested with tag
+ ``mbedtls-2.16.0``.
+
+ The ``drivers/auth/mbedtls/mbedtls_*.mk`` files contain the list of mbed TLS
+ source files the modules depend upon.
+ ``include/drivers/auth/mbedtls/mbedtls_config.h`` contains the configuration
+ options required to build the mbed TLS sources.
+
+ Note that the mbed TLS library is licensed under the Apache version 2.0
+ license. Using mbed TLS source code will affect the licensing of TF-A
+ binaries that are built using this library.
+
+#. To build the FIP image, ensure the following command line variables are set
+ while invoking ``make`` to build TF-A:
+
+ - ``MBEDTLS_DIR=<path of the directory containing mbed TLS sources>``
+ - ``TRUSTED_BOARD_BOOT=1``
+ - ``GENERATE_COT=1``
+
+ In the case of Arm platforms, the location of the ROTPK hash must also be
+ specified at build time. Two locations are currently supported (see
+ ``ARM_ROTPK_LOCATION`` build option):
+
+ - ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted
+ root-key storage registers present in the platform. On Juno, this
+ registers are read-only. On FVP Base and Cortex models, the registers
+ are read-only, but the value can be specified using the command line
+ option ``bp.trusted_key_storage.public_key`` when launching the model.
+ On both Juno and FVP models, the default value corresponds to an
+ ECDSA-SECP256R1 public key hash, whose private part is not currently
+ available.
+
+ - ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded
+ in the Arm platform port. The private/public RSA key pair may be
+ found in ``plat/arm/board/common/rotpk``.
+
+ - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded
+ in the Arm platform port. The private/public ECDSA key pair may be
+ found in ``plat/arm/board/common/rotpk``.
+
+ Example of command line using RSA development keys:
+
+ ::
+
+ MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
+ make PLAT=<platform> TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \
+ ARM_ROTPK_LOCATION=devel_rsa \
+ ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
+ BL33=<path-to>/<bl33_image> \
+ all fip
+
+ The result of this build will be the bl1.bin and the fip.bin binaries. This
+ FIP will include the certificates corresponding to the Chain of Trust
+ described in the TBBR-client document. These certificates can also be found
+ in the output build directory.
+
+#. The optional FWU_FIP contains any additional images to be loaded from
+ Non-Volatile storage during the `Firmware Update`_ process. To build the
+ FWU_FIP, any FWU images required by the platform must be specified on the
+ command line. On Arm development platforms like Juno, these are:
+
+ - NS_BL2U. The AP non-secure Firmware Updater image.
+ - SCP_BL2U. The SCP Firmware Update Configuration image.
+
+ Example of Juno command line for generating both ``fwu`` and ``fwu_fip``
+ targets using RSA development:
+
+ ::
+
+ MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
+ make PLAT=juno TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \
+ ARM_ROTPK_LOCATION=devel_rsa \
+ ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
+ BL33=<path-to>/<bl33_image> \
+ SCP_BL2=<path-to>/<scp_bl2_image> \
+ SCP_BL2U=<path-to>/<scp_bl2u_image> \
+ NS_BL2U=<path-to>/<ns_bl2u_image> \
+ all fip fwu_fip
+
+ Note: The BL2U image will be built by default and added to the FWU_FIP.
+ The user may override this by adding ``BL2U=<path-to>/<bl2u_image>``
+ to the command line above.
+
+ Note: Building and installing the non-secure and SCP FWU images (NS_BL1U,
+ NS_BL2U and SCP_BL2U) is outside the scope of this document.
+
+ The result of this build will be bl1.bin, fip.bin and fwu_fip.bin binaries.
+ Both the FIP and FWU_FIP will include the certificates corresponding to the
+ Chain of Trust described in the TBBR-client document. These certificates
+ can also be found in the output build directory.
+
+Building the Certificate Generation Tool
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``cert_create`` tool is built as part of the TF-A build process when the
+``fip`` make target is specified and TBB is enabled (as described in the
+previous section), but it can also be built separately with the following
+command:
+
+::
+
+ make PLAT=<platform> [DEBUG=1] [V=1] certtool
+
+For platforms that require their own IDs in certificate files, the generic
+'cert_create' tool can be built with the following command. Note that the target
+platform must define its IDs within a ``platform_oid.h`` header file for the
+build to succeed.
+
+::
+
+ make PLAT=<platform> USE_TBBR_DEFS=0 [DEBUG=1] [V=1] certtool
+
+``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more
+verbose. The following command should be used to obtain help about the tool:
+
+::
+
+ ./tools/cert_create/cert_create -h
+
+Building a FIP for Juno and FVP
+-------------------------------
+
+This section provides Juno and FVP specific instructions to build Trusted
+Firmware, obtain the additional required firmware, and pack it all together in
+a single FIP binary. It assumes that a `Linaro Release`_ has been installed.
+
+Note: Pre-built binaries for AArch32 are available from Linaro Release 16.12
+onwards. Before that release, pre-built binaries are only available for AArch64.
+
+Note: Follow the full instructions for one platform before switching to a
+different one. Mixing instructions for different platforms may result in
+corrupted binaries.
+
+Note: The uboot image downloaded by the Linaro workspace script does not always
+match the uboot image packaged as BL33 in the corresponding fip file. It is
+recommended to use the version that is packaged in the fip file using the
+instructions below.
+
+Note: For the FVP, the kernel FDT is packaged in FIP during build and loaded
+by the firmware at runtime. See `Obtaining the Flattened Device Trees`_
+section for more info on selecting the right FDT to use.
+
+#. Clean the working directory
+
+ ::
+
+ make realclean
+
+#. Obtain SCP_BL2 (Juno) and BL33 (all platforms)
+
+ Use the fiptool to extract the SCP_BL2 and BL33 images from the FIP
+ package included in the Linaro release:
+
+ ::
+
+ # Build the fiptool
+ make [DEBUG=1] [V=1] fiptool
+
+ # Unpack firmware images from Linaro FIP
+ ./tools/fiptool/fiptool unpack <path-to-linaro-release>/fip.bin
+
+ The unpack operation will result in a set of binary images extracted to the
+ current working directory. The SCP_BL2 image corresponds to
+ ``scp-fw.bin`` and BL33 corresponds to ``nt-fw.bin``.
+
+ Note: The fiptool will complain if the images to be unpacked already
+ exist in the current directory. If that is the case, either delete those
+ files or use the ``--force`` option to overwrite.
+
+ Note: For AArch32, the instructions below assume that nt-fw.bin is a normal
+ world boot loader that supports AArch32.
+
+#. Build TF-A images and create a new FIP for FVP
+
+ ::
+
+ # AArch64
+ make PLAT=fvp BL33=nt-fw.bin all fip
+
+ # AArch32
+ make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=nt-fw.bin all fip
+
+#. Build TF-A images and create a new FIP for Juno
+
+ For AArch64:
+
+ Building for AArch64 on Juno simply requires the addition of ``SCP_BL2``
+ as a build parameter.
+
+ ::
+
+ make PLAT=juno BL33=nt-fw.bin SCP_BL2=scp-fw.bin all fip
+
+ For AArch32:
+
+ Hardware restrictions on Juno prevent cold reset into AArch32 execution mode,
+ therefore BL1 and BL2 must be compiled for AArch64, and BL32 is compiled
+ separately for AArch32.
+
+ - Before building BL32, the environment variable ``CROSS_COMPILE`` must point
+ to the AArch32 Linaro cross compiler.
+
+ ::
+
+ export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
+
+ - Build BL32 in AArch32.
+
+ ::
+
+ make ARCH=aarch32 PLAT=juno AARCH32_SP=sp_min \
+ RESET_TO_SP_MIN=1 JUNO_AARCH32_EL3_RUNTIME=1 bl32
+
+ - Save ``bl32.bin`` to a temporary location and clean the build products.
+
+ ::
+
+ cp <path-to-build>/bl32.bin <path-to-temporary>
+ make realclean
+
+ - Before building BL1 and BL2, the environment variable ``CROSS_COMPILE``
+ must point to the AArch64 Linaro cross compiler.
+
+ ::
+
+ export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+
+ - The following parameters should be used to build BL1 and BL2 in AArch64
+ and point to the BL32 file.
+
+ ::
+
+ make ARCH=aarch64 PLAT=juno JUNO_AARCH32_EL3_RUNTIME=1 \
+ BL33=nt-fw.bin SCP_BL2=scp-fw.bin \
+ BL32=<path-to-temporary>/bl32.bin all fip
+
+The resulting BL1 and FIP images may be found in:
+
+::
+
+ # Juno
+ ./build/juno/release/bl1.bin
+ ./build/juno/release/fip.bin
+
+ # FVP
+ ./build/fvp/release/bl1.bin
+ ./build/fvp/release/fip.bin
+
+
+Booting Firmware Update images
+-------------------------------------
+
+When Firmware Update (FWU) is enabled there are at least 2 new images
+that have to be loaded, the Non-Secure FWU ROM (NS-BL1U), and the
+FWU FIP.
+
+Juno
+~~~~
+
+The new images must be programmed in flash memory by adding
+an entry in the ``SITE1/HBI0262x/images.txt`` configuration file
+on the Juno SD card (where ``x`` depends on the revision of the Juno board).
+Refer to the `Juno Getting Started Guide`_, section 2.3 "Flash memory
+programming" for more information. User should ensure these do not
+overlap with any other entries in the file.
+
+::
+
+ NOR10UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
+ NOR10ADDRESS: 0x00400000 ;Image Flash Address [ns_bl2u_base_address]
+ NOR10FILE: \SOFTWARE\fwu_fip.bin ;Image File Name
+ NOR10LOAD: 00000000 ;Image Load Address
+ NOR10ENTRY: 00000000 ;Image Entry Point
+
+ NOR11UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
+ NOR11ADDRESS: 0x03EB8000 ;Image Flash Address [ns_bl1u_base_address]
+ NOR11FILE: \SOFTWARE\ns_bl1u.bin ;Image File Name
+ NOR11LOAD: 00000000 ;Image Load Address
+
+The address ns_bl1u_base_address is the value of NS_BL1U_BASE - 0x8000000.
+In the same way, the address ns_bl2u_base_address is the value of
+NS_BL2U_BASE - 0x8000000.
+
+FVP
+~~~
+
+The additional fip images must be loaded with:
+
+::
+
+ --data cluster0.cpu0="<path_to>/ns_bl1u.bin"@0x0beb8000 [ns_bl1u_base_address]
+ --data cluster0.cpu0="<path_to>/fwu_fip.bin"@0x08400000 [ns_bl2u_base_address]
+
+The address ns_bl1u_base_address is the value of NS_BL1U_BASE.
+In the same way, the address ns_bl2u_base_address is the value of
+NS_BL2U_BASE.
+
+
+EL3 payloads alternative boot flow
+----------------------------------
+
+On a pre-production system, the ability to execute arbitrary, bare-metal code at
+the highest exception level is required. It allows full, direct access to the
+hardware, for example to run silicon soak tests.
+
+Although it is possible to implement some baremetal secure firmware from
+scratch, this is a complex task on some platforms, depending on the level of
+configuration required to put the system in the expected state.
+
+Rather than booting a baremetal application, a possible compromise is to boot
+``EL3 payloads`` through TF-A instead. This is implemented as an alternative
+boot flow, where a modified BL2 boots an EL3 payload, instead of loading the
+other BL images and passing control to BL31. It reduces the complexity of
+developing EL3 baremetal code by:
+
+- putting the system into a known architectural state;
+- taking care of platform secure world initialization;
+- loading the SCP_BL2 image if required by the platform.
+
+When booting an EL3 payload on Arm standard platforms, the configuration of the
+TrustZone controller is simplified such that only region 0 is enabled and is
+configured to permit secure access only. This gives full access to the whole
+DRAM to the EL3 payload.
+
+The system is left in the same state as when entering BL31 in the default boot
+flow. In particular:
+
+- Running in EL3;
+- Current state is AArch64;
+- Little-endian data access;
+- All exceptions disabled;
+- MMU disabled;
+- Caches disabled.
+
+Booting an EL3 payload
+~~~~~~~~~~~~~~~~~~~~~~
+
+The EL3 payload image is a standalone image and is not part of the FIP. It is
+not loaded by TF-A. Therefore, there are 2 possible scenarios:
+
+- The EL3 payload may reside in non-volatile memory (NVM) and execute in
+ place. In this case, booting it is just a matter of specifying the right
+ address in NVM through ``EL3_PAYLOAD_BASE`` when building TF-A.
+
+- The EL3 payload needs to be loaded in volatile memory (e.g. DRAM) at
+ run-time.
+
+To help in the latter scenario, the ``SPIN_ON_BL1_EXIT=1`` build option can be
+used. The infinite loop that it introduces in BL1 stops execution at the right
+moment for a debugger to take control of the target and load the payload (for
+example, over JTAG).
+
+It is expected that this loading method will work in most cases, as a debugger
+connection is usually available in a pre-production system. The user is free to
+use any other platform-specific mechanism to load the EL3 payload, though.
+
+Booting an EL3 payload on FVP
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for
+the secondary CPUs holding pen to work properly. Unfortunately, its reset value
+is undefined on the FVP platform and the FVP platform code doesn't clear it.
+Therefore, one must modify the way the model is normally invoked in order to
+clear the mailbox at start-up.
+
+One way to do that is to create an 8-byte file containing all zero bytes using
+the following command:
+
+::
+
+ dd if=/dev/zero of=mailbox.dat bs=1 count=8
+
+and pre-load it into the FVP memory at the mailbox address (i.e. ``0x04000000``)
+using the following model parameters:
+
+::
+
+ --data cluster0.cpu0=mailbox.dat@0x04000000 [Base FVPs]
+ --data=mailbox.dat@0x04000000 [Foundation FVP]
+
+To provide the model with the EL3 payload image, the following methods may be
+used:
+
+#. If the EL3 payload is able to execute in place, it may be programmed into
+ flash memory. On Base Cortex and AEM FVPs, the following model parameter
+ loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already
+ used for the FIP):
+
+ ::
+
+ -C bp.flashloader1.fname="<path-to>/<el3-payload>"
+
+ On Foundation FVP, there is no flash loader component and the EL3 payload
+ may be programmed anywhere in flash using method 3 below.
+
+#. When using the ``SPIN_ON_BL1_EXIT=1`` loading method, the following DS-5
+ command may be used to load the EL3 payload ELF image over JTAG:
+
+ ::
+
+ load <path-to>/el3-payload.elf
+
+#. The EL3 payload may be pre-loaded in volatile memory using the following
+ model parameters:
+
+ ::
+
+ --data cluster0.cpu0="<path-to>/el3-payload>"@address [Base FVPs]
+ --data="<path-to>/<el3-payload>"@address [Foundation FVP]
+
+ The address provided to the FVP must match the ``EL3_PAYLOAD_BASE`` address
+ used when building TF-A.
+
+Booting an EL3 payload on Juno
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the EL3 payload is able to execute in place, it may be programmed in flash
+memory by adding an entry in the ``SITE1/HBI0262x/images.txt`` configuration file
+on the Juno SD card (where ``x`` depends on the revision of the Juno board).
+Refer to the `Juno Getting Started Guide`_, section 2.3 "Flash memory
+programming" for more information.
+
+Alternatively, the same DS-5 command mentioned in the FVP section above can
+be used to load the EL3 payload's ELF file over JTAG on Juno.
+
+Preloaded BL33 alternative boot flow
+------------------------------------
+
+Some platforms have the ability to preload BL33 into memory instead of relying
+on TF-A to load it. This may simplify packaging of the normal world code and
+improve performance in a development environment. When secure world cold boot
+is complete, TF-A simply jumps to a BL33 base address provided at build time.
+
+For this option to be used, the ``PRELOADED_BL33_BASE`` build option has to be
+used when compiling TF-A. For example, the following command will create a FIP
+without a BL33 and prepare to jump to a BL33 image loaded at address
+0x80000000:
+
+::
+
+ make PRELOADED_BL33_BASE=0x80000000 PLAT=fvp all fip
+
+Boot of a preloaded kernel image on Base FVP
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following example uses a simplified boot flow by directly jumping from the
+TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
+useful if both the kernel and the device tree blob (DTB) are already present in
+memory (like in FVP).
+
+For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
+address ``0x82000000``, the firmware can be built like this:
+
+::
+
+ CROSS_COMPILE=aarch64-linux-gnu- \
+ make PLAT=fvp DEBUG=1 \
+ RESET_TO_BL31=1 \
+ ARM_LINUX_KERNEL_AS_BL33=1 \
+ PRELOADED_BL33_BASE=0x80080000 \
+ ARM_PRELOADED_DTB_BASE=0x82000000 \
+ all fip
+
+Now, it is needed to modify the DTB so that the kernel knows the address of the
+ramdisk. The following script generates a patched DTB from the provided one,
+assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
+script assumes that the user is using a ramdisk image prepared for U-Boot, like
+the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
+offset in ``INITRD_START`` has to be removed.
+
+.. code:: bash
+
+ #!/bin/bash
+
+ # Path to the input DTB
+ KERNEL_DTB=<path-to>/<fdt>
+ # Path to the output DTB
+ PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
+ # Base address of the ramdisk
+ INITRD_BASE=0x84000000
+ # Path to the ramdisk
+ INITRD=<path-to>/<ramdisk.img>
+
+ # Skip uboot header (64 bytes)
+ INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
+ INITRD_SIZE=$(stat -Lc %s ${INITRD})
+ INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
+
+ CHOSEN_NODE=$(echo \
+ "/ { \
+ chosen { \
+ linux,initrd-start = <${INITRD_START}>; \
+ linux,initrd-end = <${INITRD_END}>; \
+ }; \
+ };")
+
+ echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} | \
+ dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
+
+And the FVP binary can be run with the following command:
+
+::
+
+ <path-to>/FVP_Base_AEMv8A-AEMv8A \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C cluster0.NUM_CORES=4 \
+ -C cluster1.NUM_CORES=4 \
+ -C cache_state_modelled=1 \
+ -C cluster0.cpu0.RVBAR=0x04020000 \
+ -C cluster0.cpu1.RVBAR=0x04020000 \
+ -C cluster0.cpu2.RVBAR=0x04020000 \
+ -C cluster0.cpu3.RVBAR=0x04020000 \
+ -C cluster1.cpu0.RVBAR=0x04020000 \
+ -C cluster1.cpu1.RVBAR=0x04020000 \
+ -C cluster1.cpu2.RVBAR=0x04020000 \
+ -C cluster1.cpu3.RVBAR=0x04020000 \
+ --data cluster0.cpu0="<path-to>/bl31.bin"@0x04020000 \
+ --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000 \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
+
+Boot of a preloaded kernel image on Juno
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Trusted Firmware must be compiled in a similar way as for FVP explained
+above. The process to load binaries to memory is the one explained in
+`Booting an EL3 payload on Juno`_.
+
+Running the software on FVP
+---------------------------
+
+The latest version of the AArch64 build of TF-A has been tested on the following
+Arm FVPs without shifted affinities, and that do not support threaded CPU cores
+(64-bit host machine only).
+
+The FVP models used are Version 11.6 Build 45, unless otherwise stated.
+
+- ``FVP_Base_AEMv8A-AEMv8A``
+- ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
+- ``FVP_Base_RevC-2xAEMv8A``
+- ``FVP_Base_Cortex-A32x4``
+- ``FVP_Base_Cortex-A35x4``
+- ``FVP_Base_Cortex-A53x4``
+- ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
+- ``FVP_Base_Cortex-A55x4``
+- ``FVP_Base_Cortex-A57x1-A53x1``
+- ``FVP_Base_Cortex-A57x2-A53x4``
+- ``FVP_Base_Cortex-A57x4-A53x4``
+- ``FVP_Base_Cortex-A57x4``
+- ``FVP_Base_Cortex-A72x4-A53x4``
+- ``FVP_Base_Cortex-A72x4``
+- ``FVP_Base_Cortex-A73x4-A53x4``
+- ``FVP_Base_Cortex-A73x4``
+- ``FVP_Base_Cortex-A75x4``
+- ``FVP_Base_Cortex-A76x4``
+- ``FVP_Base_Cortex-A76AEx4``
+- ``FVP_Base_Cortex-A76AEx8``
+- ``FVP_Base_Neoverse-N1x4``
+- ``FVP_Base_Deimos``
+- ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
+- ``FVP_CSS_SGM-775`` (Version 11.3 build 42)
+- ``FVP_RD_E1Edge`` (Version 11.3 build 42)
+- ``FVP_RD_N1Edge``
+- ``Foundation_Platform``
+
+The latest version of the AArch32 build of TF-A has been tested on the following
+Arm FVPs without shifted affinities, and that do not support threaded CPU cores
+(64-bit host machine only).
+
+- ``FVP_Base_AEMv8A-AEMv8A``
+- ``FVP_Base_Cortex-A32x4``
+
+NOTE: The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities, which
+is not compatible with legacy GIC configurations. Therefore this FVP does not
+support these legacy GIC configurations.
+
+NOTE: The build numbers quoted above are those reported by launching the FVP
+with the ``--version`` parameter.
+
+NOTE: Linaro provides a ramdisk image in prebuilt FVP configurations and full
+file systems that can be downloaded separately. To run an FVP with a virtio
+file system image an additional FVP configuration option
+``-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>`` can be
+used.
+
+NOTE: The software will not work on Version 1.0 of the Foundation FVP.
+The commands below would report an ``unhandled argument`` error in this case.
+
+NOTE: FVPs can be launched with ``--cadi-server`` option such that a
+CADI-compliant debugger (for example, Arm DS-5) can connect to and control its
+execution.
+
+NOTE: Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
+the internal synchronisation timings changed compared to older versions of the
+models. The models can be launched with ``-Q 100`` option if they are required
+to match the run time characteristics of the older versions.
+
+The Foundation FVP is a cut down version of the AArch64 Base FVP. It can be
+downloaded for free from `Arm's website`_.
+
+The Cortex-A models listed above are also available to download from
+`Arm's website`_.
+
+Please refer to the FVP documentation for a detailed description of the model
+parameter options. A brief description of the important ones that affect TF-A
+and normal world software behavior is provided below.
+
+Obtaining the Flattened Device Trees
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Depending on the FVP configuration and Linux configuration used, different
+FDT files are required. FDT source files for the Foundation and Base FVPs can
+be found in the TF-A source directory under ``fdts/``. The Foundation FVP has
+a subset of the Base FVP components. For example, the Foundation FVP lacks
+CLCD and MMC support, and has only one CPU cluster.
+
+Note: It is not recommended to use the FDTs built along the kernel because not
+all FDTs are available from there.
+
+The dynamic configuration capability is enabled in the firmware for FVPs.
+This means that the firmware can authenticate and load the FDT if present in
+FIP. A default FDT is packaged into FIP during the build based on
+the build configuration. This can be overridden by using the ``FVP_HW_CONFIG``
+or ``FVP_HW_CONFIG_DTS`` build options (refer to the
+`Arm FVP platform specific build options`_ section for detail on the options).
+
+- ``fvp-base-gicv2-psci.dts``
+
+ For use with models such as the Cortex-A57-A53 Base FVPs without shifted
+ affinities and with Base memory map configuration.
+
+- ``fvp-base-gicv2-psci-aarch32.dts``
+
+ For use with models such as the Cortex-A32 Base FVPs without shifted
+ affinities and running Linux in AArch32 state with Base memory map
+ configuration.
+
+- ``fvp-base-gicv3-psci.dts``
+
+ For use with models such as the Cortex-A57-A53 Base FVPs without shifted
+ affinities and with Base memory map configuration and Linux GICv3 support.
+
+- ``fvp-base-gicv3-psci-1t.dts``
+
+ For use with models such as the AEMv8-RevC Base FVP with shifted affinities,
+ single threaded CPUs, Base memory map configuration and Linux GICv3 support.
+
+- ``fvp-base-gicv3-psci-dynamiq.dts``
+
+ For use with models as the Cortex-A55-A75 Base FVPs with shifted affinities,
+ single cluster, single threaded CPUs, Base memory map configuration and Linux
+ GICv3 support.
+
+- ``fvp-base-gicv3-psci-aarch32.dts``
+
+ For use with models such as the Cortex-A32 Base FVPs without shifted
+ affinities and running Linux in AArch32 state with Base memory map
+ configuration and Linux GICv3 support.
+
+- ``fvp-foundation-gicv2-psci.dts``
+
+ For use with Foundation FVP with Base memory map configuration.
+
+- ``fvp-foundation-gicv3-psci.dts``
+
+ (Default) For use with Foundation FVP with Base memory map configuration
+ and Linux GICv3 support.
+
+Running on the Foundation FVP with reset to BL1 entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``Foundation_Platform`` parameters should be used to boot Linux with
+4 CPUs using the AArch64 build of TF-A.
+
+::
+
+ <path-to>/Foundation_Platform \
+ --cores=4 \
+ --arm-v8.0 \
+ --secure-memory \
+ --visualization \
+ --gicv3 \
+ --data="<path-to>/<bl1-binary>"@0x0 \
+ --data="<path-to>/<FIP-binary>"@0x08000000 \
+ --data="<path-to>/<kernel-binary>"@0x80080000 \
+ --data="<path-to>/<ramdisk-binary>"@0x84000000
+
+Notes:
+
+- BL1 is loaded at the start of the Trusted ROM.
+- The Firmware Image Package is loaded at the start of NOR FLASH0.
+- The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
+ is specified via the ``hw_config_addr`` property in `TB_FW_CONFIG for FVP`_.
+- The default use-case for the Foundation FVP is to use the ``--gicv3`` option
+ and enable the GICv3 device in the model. Note that without this option,
+ the Foundation FVP defaults to legacy (Versatile Express) memory map which
+ is not supported by TF-A.
+- In order for TF-A to run correctly on the Foundation FVP, the architecture
+ versions must match. The Foundation FVP defaults to the highest v8.x
+ version it supports but the default build for TF-A is for v8.0. To avoid
+ issues either start the Foundation FVP to use v8.0 architecture using the
+ ``--arm-v8.0`` option, or build TF-A with an appropriate value for
+ ``ARM_ARCH_MINOR``.
+
+Running on the AEMv8 Base FVP with reset to BL1 entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch64 build of TF-A.
+
+::
+
+ <path-to>/FVP_Base_RevC-2xAEMv8A \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C bp.tzc_400.diagnostics=1 \
+ -C cluster0.NUM_CORES=4 \
+ -C cluster1.NUM_CORES=4 \
+ -C cache_state_modelled=1 \
+ -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
+ -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Note: The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
+specific DTS for all the CPUs to be loaded.
+
+Running on the AEMv8 Base FVP (AArch32) with reset to BL1 entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of TF-A.
+
+::
+
+ <path-to>/FVP_Base_AEMv8A-AEMv8A \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C bp.tzc_400.diagnostics=1 \
+ -C cluster0.NUM_CORES=4 \
+ -C cluster1.NUM_CORES=4 \
+ -C cache_state_modelled=1 \
+ -C cluster0.cpu0.CONFIG64=0 \
+ -C cluster0.cpu1.CONFIG64=0 \
+ -C cluster0.cpu2.CONFIG64=0 \
+ -C cluster0.cpu3.CONFIG64=0 \
+ -C cluster1.cpu0.CONFIG64=0 \
+ -C cluster1.cpu1.CONFIG64=0 \
+ -C cluster1.cpu2.CONFIG64=0 \
+ -C cluster1.cpu3.CONFIG64=0 \
+ -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
+ -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
+boot Linux with 8 CPUs using the AArch64 build of TF-A.
+
+::
+
+ <path-to>/FVP_Base_Cortex-A57x4-A53x4 \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C bp.tzc_400.diagnostics=1 \
+ -C cache_state_modelled=1 \
+ -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
+ -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Running on the Cortex-A32 Base FVP (AArch32) with reset to BL1 entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of TF-A.
+
+::
+
+ <path-to>/FVP_Base_Cortex-A32x4 \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C bp.tzc_400.diagnostics=1 \
+ -C cache_state_modelled=1 \
+ -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
+ -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Running on the AEMv8 Base FVP with reset to BL31 entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch64 build of TF-A.
+
+::
+
+ <path-to>/FVP_Base_RevC-2xAEMv8A \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C bp.tzc_400.diagnostics=1 \
+ -C cluster0.NUM_CORES=4 \
+ -C cluster1.NUM_CORES=4 \
+ -C cache_state_modelled=1 \
+ -C cluster0.cpu0.RVBAR=0x04010000 \
+ -C cluster0.cpu1.RVBAR=0x04010000 \
+ -C cluster0.cpu2.RVBAR=0x04010000 \
+ -C cluster0.cpu3.RVBAR=0x04010000 \
+ -C cluster1.cpu0.RVBAR=0x04010000 \
+ -C cluster1.cpu1.RVBAR=0x04010000 \
+ -C cluster1.cpu2.RVBAR=0x04010000 \
+ -C cluster1.cpu3.RVBAR=0x04010000 \
+ --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000 \
+ --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000 \
+ --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
+ --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000 \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Notes:
+
+- If Position Independent Executable (PIE) support is enabled for BL31
+ in this config, it can be loaded at any valid address for execution.
+
+- Since a FIP is not loaded when using BL31 as reset entrypoint, the
+ ``--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>``
+ parameter is needed to load the individual bootloader images in memory.
+ BL32 image is only needed if BL31 has been built to expect a Secure-EL1
+ Payload. For the same reason, the FDT needs to be compiled from the DT source
+ and loaded via the ``--data cluster0.cpu0="<path-to>/<fdt>"@0x82000000``
+ parameter.
+
+- The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
+ specific DTS for all the CPUs to be loaded.
+
+- The ``-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>`` parameter, where
+ X and Y are the cluster and CPU numbers respectively, is used to set the
+ reset vector for each core.
+
+- Changing the default value of ``ARM_TSP_RAM_LOCATION`` will also require
+ changing the value of
+ ``--data="<path-to><bl32-binary>"@<base-address-of-bl32>`` to the new value of
+ ``BL32_BASE``.
+
+Running on the AEMv8 Base FVP (AArch32) with reset to SP_MIN entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
+with 8 CPUs using the AArch32 build of TF-A.
+
+::
+
+ <path-to>/FVP_Base_AEMv8A-AEMv8A \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C bp.tzc_400.diagnostics=1 \
+ -C cluster0.NUM_CORES=4 \
+ -C cluster1.NUM_CORES=4 \
+ -C cache_state_modelled=1 \
+ -C cluster0.cpu0.CONFIG64=0 \
+ -C cluster0.cpu1.CONFIG64=0 \
+ -C cluster0.cpu2.CONFIG64=0 \
+ -C cluster0.cpu3.CONFIG64=0 \
+ -C cluster1.cpu0.CONFIG64=0 \
+ -C cluster1.cpu1.CONFIG64=0 \
+ -C cluster1.cpu2.CONFIG64=0 \
+ -C cluster1.cpu3.CONFIG64=0 \
+ -C cluster0.cpu0.RVBAR=0x04002000 \
+ -C cluster0.cpu1.RVBAR=0x04002000 \
+ -C cluster0.cpu2.RVBAR=0x04002000 \
+ -C cluster0.cpu3.RVBAR=0x04002000 \
+ -C cluster1.cpu0.RVBAR=0x04002000 \
+ -C cluster1.cpu1.RVBAR=0x04002000 \
+ -C cluster1.cpu2.RVBAR=0x04002000 \
+ -C cluster1.cpu3.RVBAR=0x04002000 \
+ --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000 \
+ --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
+ --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000 \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Note: The load address of ``<bl32-binary>`` depends on the value ``BL32_BASE``.
+It should match the address programmed into the RVBAR register as well.
+
+Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
+boot Linux with 8 CPUs using the AArch64 build of TF-A.
+
+::
+
+ <path-to>/FVP_Base_Cortex-A57x4-A53x4 \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C bp.tzc_400.diagnostics=1 \
+ -C cache_state_modelled=1 \
+ -C cluster0.cpu0.RVBARADDR=0x04010000 \
+ -C cluster0.cpu1.RVBARADDR=0x04010000 \
+ -C cluster0.cpu2.RVBARADDR=0x04010000 \
+ -C cluster0.cpu3.RVBARADDR=0x04010000 \
+ -C cluster1.cpu0.RVBARADDR=0x04010000 \
+ -C cluster1.cpu1.RVBARADDR=0x04010000 \
+ -C cluster1.cpu2.RVBARADDR=0x04010000 \
+ -C cluster1.cpu3.RVBARADDR=0x04010000 \
+ --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000 \
+ --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000 \
+ --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
+ --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000 \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Running on the Cortex-A32 Base FVP (AArch32) with reset to SP_MIN entrypoint
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
+boot Linux with 4 CPUs using the AArch32 build of TF-A.
+
+::
+
+ <path-to>/FVP_Base_Cortex-A32x4 \
+ -C pctl.startup=0.0.0.0 \
+ -C bp.secure_memory=1 \
+ -C bp.tzc_400.diagnostics=1 \
+ -C cache_state_modelled=1 \
+ -C cluster0.cpu0.RVBARADDR=0x04002000 \
+ -C cluster0.cpu1.RVBARADDR=0x04002000 \
+ -C cluster0.cpu2.RVBARADDR=0x04002000 \
+ -C cluster0.cpu3.RVBARADDR=0x04002000 \
+ --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000 \
+ --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
+ --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000 \
+ --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
+ --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
+
+Running the software on Juno
+----------------------------
+
+This version of TF-A has been tested on variants r0, r1 and r2 of Juno.
+
+To execute the software stack on Juno, the version of the Juno board recovery
+image indicated in the `Linaro Release Notes`_ must be installed. If you have an
+earlier version installed or are unsure which version is installed, please
+re-install the recovery image by following the
+`Instructions for using Linaro's deliverables on Juno`_.
+
+Preparing TF-A images
+~~~~~~~~~~~~~~~~~~~~~
+
+After building TF-A, the files ``bl1.bin`` and ``fip.bin`` need copying to the
+``SOFTWARE/`` directory of the Juno SD card.
+
+Other Juno software information
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Please visit the `Arm Platforms Portal`_ to get support and obtain any other Juno
+software information. Please also refer to the `Juno Getting Started Guide`_ to
+get more detailed information about the Juno Arm development platform and how to
+configure it.
+
+Testing SYSTEM SUSPEND on Juno
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The SYSTEM SUSPEND is a PSCI API which can be used to implement system suspend
+to RAM. For more details refer to section 5.16 of `PSCI`_. To test system suspend
+on Juno, at the linux shell prompt, issue the following command:
+
+::
+
+ echo +10 > /sys/class/rtc/rtc0/wakealarm
+ echo -n mem > /sys/power/state
+
+The Juno board should suspend to RAM and then wakeup after 10 seconds due to
+wakeup interrupt from RTC.
+
+--------------
+
+*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _arm Developer page: https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads
+.. _Linaro: `Linaro Release Notes`_
+.. _Linaro Release: `Linaro Release Notes`_
+.. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
+.. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables
+.. _Instructions for using Linaro's deliverables on Juno: https://community.arm.com/dev-platforms/w/docs/303/juno
+.. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
+.. _Development Studio 5 (DS-5): https://developer.arm.com/products/software-development-tools/ds-5-development-studio
+.. _arm-trusted-firmware-a project page: https://review.trustedfirmware.org/admin/projects/TF-A/trusted-firmware-a
+.. _`Linux Coding Style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
+.. _Linux master tree: https://github.com/torvalds/linux/tree/master/
+.. _Dia: https://wiki.gnome.org/Apps/Dia/Download
+.. _here: psci-lib-integration-guide.rst
+.. _Trusted Board Boot: trusted-board-boot.rst
+.. _TB_FW_CONFIG for FVP: ../plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
+.. _Secure-EL1 Payloads and Dispatchers: firmware-design.rst#user-content-secure-el1-payloads-and-dispatchers
+.. _Firmware Update: firmware-update.rst
+.. _Firmware Design: firmware-design.rst
+.. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
+.. _mbed TLS Security Center: https://tls.mbed.org/security
+.. _Arm's website: `FVP models`_
+.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
+.. _Juno Getting Started Guide: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf
+.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _Secure Partition Manager Design guide: secure-partition-manager-design.rst
+.. _`Trusted Firmware-A Coding Guidelines`: coding-guidelines.rst
+.. _`Library at ROM`: romlib-design.rst
+++ /dev/null
-Image Terminology
-=================
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-This page contains the current name, abbreviated name and purpose of the various
-images referred to in the Trusted Firmware project.
-
-General Notes
--------------
-
-- Some of the names and abbreviated names have changed to accomodate new
- requirements. The changed names are as backward compatible as possible to
- minimize confusion. Where applicable, the previous names are indicated. Some
- code, documentation and build artefacts may still refer to the previous names;
- these will inevitably take time to catch up.
-
-- The main name change is to prefix each image with the processor it corresponds
- to (for example ``AP_``, ``SCP_``, ...). In situations where there is no
- ambiguity (for example, within AP specific code/documentation), it is
- permitted to omit the processor prefix (for example, just BL1 instead of
- ``AP_BL1``).
-
-- Previously, the format for 3rd level images had 2 forms; ``BL3`` was either
- suffixed with a dash ("-") followed by a number (for example, ``BL3-1``) or a
- subscript number, depending on whether rich text formatting was available.
- This was confusing and often the dash gets omitted in practice. Therefore the
- new form is to just omit the dash and not use subscript formatting.
-
-- The names no longer contain dash ("-") characters at all. In some places (for
- example, function names) it's not possible to use this character. All dashes
- are either removed or replaced by underscores ("_").
-
-- The abbreviation BL stands for BootLoader. This is a historical anomaly.
- Clearly, many of these images are not BootLoaders, they are simply firmware
- images. However, the BL abbreviation is now widely used and is retained for
- backwards compatibility.
-
-- The image names are not case sensitive. For example, ``bl1`` is
- interchangeable with ``BL1``, although mixed case should be avoided.
-
-Trusted Firmware Images
------------------------
-
-AP Boot ROM: ``AP_BL1``
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Typically, this is the first code to execute on the AP and cannot be modified.
-Its primary purpose is to perform the minimum intialization necessary to load
-and authenticate an updateable AP firmware image into an executable RAM
-location, then hand-off control to that image.
-
-AP RAM Firmware: ``AP_BL2``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is the 2nd stage AP firmware. It is currently also known as the "Trusted
-Boot Firmware". Its primary purpose is to perform any additional initialization
-required to load and authenticate all 3rd level firmware images into their
-executable RAM locations, then hand-off control to the EL3 Runtime Firmware.
-
-EL3 Runtime Firmware: ``AP_BL31``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Also known as "SoC AP firmware" or "EL3 monitor firmware". Its primary purpose
-is to handle transitions between the normal and secure world.
-
-Secure-EL1 Payload (SP): ``AP_BL32``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Typically this is a TEE or Trusted OS, providing runtime secure services to the
-normal world. However, it may refer to a more abstract Secure-EL1 Payload (SP).
-Note that this abbreviation should only be used in systems where there is a
-single or primary image executing at Secure-EL1. In systems where there are
-potentially multiple SPs and there is no concept of a primary SP, this
-abbreviation should be avoided; use the recommended **Other AP 3rd level
-images** abbreviation instead.
-
-AP Normal World Firmware: ``AP_BL33``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-For example, UEFI or uboot. Its primary purpose is to boot a normal world OS.
-
-Other AP 3rd level images: ``AP_BL3_XXX``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The abbreviated names of the existing 3rd level images imply a load/execution
-ordering (for example, ``AP_BL31 -> AP_BL32 -> AP_BL33``). Some systems may
-have additional images and/or a different load/execution ordering. The
-abbreviated names of the existing images are retained for backward compatibility
-but new 3rd level images should be suffixed with an underscore followed by text
-identifier, not a number.
-
-In systems where 3rd level images are provided by different vendors, the
-abbreviated name should identify the vendor as well as the image
-function. For example, ``AP_BL3_ARM_RAS``.
-
-SCP Boot ROM: ``SCP_BL1`` (previously ``BL0``)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Typically, this is the first code to execute on the SCP and cannot be modified.
-Its primary purpose is to perform the minimum intialization necessary to load
-and authenticate an updateable SCP firmware image into an executable RAM
-location, then hand-off control to that image. This may be performed in
-conjunction with other processor firmware (for example, ``AP_BL1`` and
-``AP_BL2``).
-
-This image was previously abbreviated as ``BL0`` but in some systems, the SCP
-may directly load/authenticate its own firmware. In these systems, it doesn't
-make sense to interleave the image terminology for AP and SCP; both AP and SCP
-Boot ROMs are ``BL1`` from their own point of view.
-
-SCP RAM Firmware: ``SCP_BL2`` (previously ``BL3-0``)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is the 2nd stage SCP firmware. It is currently also known as the "SCP
-runtime firmware" but it could potentially be an intermediate firmware if the
-SCP needs to load/authenticate multiple 3rd level images in future.
-
-This image was previously abbreviated as BL3-0 but from the SCP's point of view,
-this has always been the 2nd stage firmware. The previous name is too
-AP-centric.
-
-Firmware Update (FWU) Images
-----------------------------
-
-The terminology for these images has not been widely adopted yet but they have
-to be considered in a production Trusted Board Boot solution.
-
-AP Firmware Update Boot ROM: ``AP_NS_BL1U``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Typically, this is the first normal world code to execute on the AP during a
-firmware update operation, and cannot be modified. Its primary purpose is to
-load subequent firmware update images from an external interface and communicate
-with ``AP_BL1`` to authenticate those images.
-
-During firmware update, there are (potentially) multiple transitions between the
-secure and normal world. The "level" of the BL image is relative to the world
-it's in so it makes sense to encode "NS" in the normal world images. The absence
-of "NS" implies a secure world image.
-
-AP Firmware Update Config: ``AP_BL2U``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This image does the minimum necessary AP secure world configuration required to
-complete the firmware update operation. It is potentially a subset of ``AP_BL2``
-functionality.
-
-SCP Firmware Update Config: ``SCP_BL2U`` (previously ``BL2-U0``)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This image does the minimum necessary SCP secure world configuration required to
-complete the firmware update operation. It is potentially a subset of
-``SCP_BL2`` functionality.
-
-AP Firmware Updater: ``AP_NS_BL2U`` (previously ``BL3-U``)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This is the 2nd stage AP normal world firmware updater. Its primary purpose is
-to load a new set of firmware images from an external interface and write them
-into non-volatile storage.
-
-Other Processor Firmware Images
--------------------------------
-
-Some systems may have additional processors to the AP and SCP. For example, a
-Management Control Processor (MCP). Images for these processors should follow
-the same terminology, with the processor abbreviation prefix, followed by
-underscore and the level of the firmware image.
-
-For example,
-
-MCP Boot ROM: ``MCP_BL1``
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-MCP RAM Firmware: ``MCP_BL2``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Arm Trusted Firmware-A Documentation Index
-==========================================
+Trusted Firmware-A Documentation
+================================
.. toctree::
:maxdepth: 1
- :caption: Design Documents
+ :caption: Contents
- arm-sip-service
- auth-framework
-
- .. toctree::
- :maxdepth: 1
- :caption: Release Notes
+ getting_started/index
+ process/index
+ components/index
+ design/index
+ plat/index
+ perf/index
+ security_advisories/index
+ readme
change-log
-
- .. toctree::
- :maxdepth: 1
- :caption: Guides
-
- .. toctree::
- :maxdepth: 1
- :caption: Policies
- cpu-specific-build-macros
- exception-handling
- firmware-design
- firmware-update
- interrupt-framework-design
- platform-compatibility-policy
- platform-interrupt-controller-API
- porting-guide
- psci-lib-integration-guide
- psci-pd-tree
- ras
- reset-design
- rt-svc-writers-guide
- sdei
- secure-partition-manager-design
- trusted-board-boot
- user-guide
- xlat-tables-lib-v2-design
+ maintainers
+ acknowledgements
Indices and tables
==================
+++ /dev/null
-Trusted Firmware-A interrupt management design guide
-====================================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-This framework is responsible for managing interrupts routed to EL3. It also
-allows EL3 software to configure the interrupt routing behavior. Its main
-objective is to implement the following two requirements.
-
-#. It should be possible to route interrupts meant to be handled by secure
- software (Secure interrupts) to EL3, when execution is in non-secure state
- (normal world). The framework should then take care of handing control of
- the interrupt to either software in EL3 or Secure-EL1 depending upon the
- software configuration and the GIC implementation. This requirement ensures
- that secure interrupts are under the control of the secure software with
- respect to their delivery and handling without the possibility of
- intervention from non-secure software.
-
-#. It should be possible to route interrupts meant to be handled by
- non-secure software (Non-secure interrupts) to the last executed exception
- level in the normal world when the execution is in secure world at
- exception levels lower than EL3. This could be done with or without the
- knowledge of software executing in Secure-EL1/Secure-EL0. The choice of
- approach should be governed by the secure software. This requirement
- ensures that non-secure software is able to execute in tandem with the
- secure software without overriding it.
-
-Concepts
---------
-
-Interrupt types
-~~~~~~~~~~~~~~~
-
-The framework categorises an interrupt to be one of the following depending upon
-the exception level(s) it is handled in.
-
-#. Secure EL1 interrupt. This type of interrupt can be routed to EL3 or
- Secure-EL1 depending upon the security state of the current execution
- context. It is always handled in Secure-EL1.
-
-#. Non-secure interrupt. This type of interrupt can be routed to EL3,
- Secure-EL1, Non-secure EL1 or EL2 depending upon the security state of the
- current execution context. It is always handled in either Non-secure EL1
- or EL2.
-
-#. EL3 interrupt. This type of interrupt can be routed to EL3 or Secure-EL1
- depending upon the security state of the current execution context. It is
- always handled in EL3.
-
-The following constants define the various interrupt types in the framework
-implementation.
-
-::
-
- #define INTR_TYPE_S_EL1 0
- #define INTR_TYPE_EL3 1
- #define INTR_TYPE_NS 2
-
-Routing model
-~~~~~~~~~~~~~
-
-A type of interrupt can be either generated as an FIQ or an IRQ. The target
-exception level of an interrupt type is configured through the FIQ and IRQ bits
-in the Secure Configuration Register at EL3 (``SCR_EL3.FIQ`` and ``SCR_EL3.IRQ``
-bits). When ``SCR_EL3.FIQ``\ =1, FIQs are routed to EL3. Otherwise they are routed
-to the First Exception Level (FEL) capable of handling interrupts. When
-``SCR_EL3.IRQ``\ =1, IRQs are routed to EL3. Otherwise they are routed to the
-FEL. This register is configured independently by EL3 software for each security
-state prior to entry into a lower exception level in that security state.
-
-A routing model for a type of interrupt (generated as FIQ or IRQ) is defined as
-its target exception level for each security state. It is represented by a
-single bit for each security state. A value of ``0`` means that the interrupt
-should be routed to the FEL. A value of ``1`` means that the interrupt should be
-routed to EL3. A routing model is applicable only when execution is not in EL3.
-
-The default routing model for an interrupt type is to route it to the FEL in
-either security state.
-
-Valid routing models
-~~~~~~~~~~~~~~~~~~~~
-
-The framework considers certain routing models for each type of interrupt to be
-incorrect as they conflict with the requirements mentioned in Section 1. The
-following sub-sections describe all the possible routing models and specify
-which ones are valid or invalid. EL3 interrupts are currently supported only
-for GIC version 3.0 (Arm GICv3) and only the Secure-EL1 and Non-secure interrupt
-types are supported for GIC version 2.0 (Arm GICv2) (see `Assumptions in
-Interrupt Management Framework`_). The terminology used in the following
-sub-sections is explained below.
-
-#. **CSS**. Current Security State. ``0`` when secure and ``1`` when non-secure
-
-#. **TEL3**. Target Exception Level 3. ``0`` when targeted to the FEL. ``1`` when
- targeted to EL3.
-
-Secure-EL1 interrupts
-^^^^^^^^^^^^^^^^^^^^^
-
-#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in
- secure state. This is a valid routing model as secure software is in
- control of handling secure interrupts.
-
-#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in secure
- state. This is a valid routing model as secure software in EL3 can
- handover the interrupt to Secure-EL1 for handling.
-
-#. **CSS=1, TEL3=0**. Interrupt is routed to the FEL when execution is in
- non-secure state. This is an invalid routing model as a secure interrupt
- is not visible to the secure software which violates the motivation behind
- the Arm Security Extensions.
-
-#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in
- non-secure state. This is a valid routing model as secure software in EL3
- can handover the interrupt to Secure-EL1 for handling.
-
-Non-secure interrupts
-^^^^^^^^^^^^^^^^^^^^^
-
-#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in
- secure state. This allows the secure software to trap non-secure
- interrupts, perform its book-keeping and hand the interrupt to the
- non-secure software through EL3. This is a valid routing model as secure
- software is in control of how its execution is preempted by non-secure
- interrupts.
-
-#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in secure
- state. This is a valid routing model as secure software in EL3 can save
- the state of software in Secure-EL1/Secure-EL0 before handing the
- interrupt to non-secure software. This model requires additional
- coordination between Secure-EL1 and EL3 software to ensure that the
- former's state is correctly saved by the latter.
-
-#. **CSS=1, TEL3=0**. Interrupt is routed to FEL when execution is in
- non-secure state. This is a valid routing model as a non-secure interrupt
- is handled by non-secure software.
-
-#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in
- non-secure state. This is an invalid routing model as there is no valid
- reason to route the interrupt to EL3 software and then hand it back to
- non-secure software for handling.
-
-EL3 interrupts
-^^^^^^^^^^^^^^
-
-#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in
- Secure-EL1/Secure-EL0. This is a valid routing model as secure software
- in Secure-EL1/Secure-EL0 is in control of how its execution is preempted
- by EL3 interrupt and can handover the interrupt to EL3 for handling.
-
- However, when ``EL3_EXCEPTION_HANDLING`` is ``1``, this routing model is
- invalid as EL3 interrupts are unconditionally routed to EL3, and EL3
- interrupts will always preempt Secure EL1/EL0 execution. See `exception
- handling`__ documentation.
-
- .. __: exception-handling.rst#interrupt-handling
-
-#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in
- Secure-EL1/Secure-EL0. This is a valid routing model as secure software
- in EL3 can handle the interrupt.
-
-#. **CSS=1, TEL3=0**. Interrupt is routed to the FEL when execution is in
- non-secure state. This is an invalid routing model as a secure interrupt
- is not visible to the secure software which violates the motivation behind
- the Arm Security Extensions.
-
-#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in
- non-secure state. This is a valid routing model as secure software in EL3
- can handle the interrupt.
-
-Mapping of interrupt type to signal
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The framework is meant to work with any interrupt controller implemented by a
-platform. A interrupt controller could generate a type of interrupt as either an
-FIQ or IRQ signal to the CPU depending upon the current security state. The
-mapping between the type and signal is known only to the platform. The framework
-uses this information to determine whether the IRQ or the FIQ bit should be
-programmed in ``SCR_EL3`` while applying the routing model for a type of
-interrupt. The platform provides this information through the
-``plat_interrupt_type_to_line()`` API (described in the
-`Porting Guide`_). For example, on the FVP port when the platform uses an Arm GICv2
-interrupt controller, Secure-EL1 interrupts are signaled through the FIQ signal
-while Non-secure interrupts are signaled through the IRQ signal. This applies
-when execution is in either security state.
-
-Effect of mapping of several interrupt types to one signal
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-It should be noted that if more than one interrupt type maps to a single
-interrupt signal, and if any one of the interrupt type sets **TEL3=1** for a
-particular security state, then interrupt signal will be routed to EL3 when in
-that security state. This means that all the other interrupt types using the
-same interrupt signal will be forced to the same routing model. This should be
-borne in mind when choosing the routing model for an interrupt type.
-
-For example, in Arm GICv3, when the execution context is Secure-EL1/
-Secure-EL0, both the EL3 and the non secure interrupt types map to the FIQ
-signal. So if either one of the interrupt type sets the routing model so
-that **TEL3=1** when **CSS=0**, the FIQ bit in ``SCR_EL3`` will be programmed to
-route the FIQ signal to EL3 when executing in Secure-EL1/Secure-EL0, thereby
-effectively routing the other interrupt type also to EL3.
-
-Assumptions in Interrupt Management Framework
----------------------------------------------
-
-The framework makes the following assumptions to simplify its implementation.
-
-#. Although the framework has support for 2 types of secure interrupts (EL3
- and Secure-EL1 interrupt), only interrupt controller architectures
- like Arm GICv3 has architectural support for EL3 interrupts in the form of
- Group 0 interrupts. In Arm GICv2, all secure interrupts are assumed to be
- handled in Secure-EL1. They can be delivered to Secure-EL1 via EL3 but they
- cannot be handled in EL3.
-
-#. Interrupt exceptions (``PSTATE.I`` and ``F`` bits) are masked during execution
- in EL3.
-
-#. Interrupt management: the following sections describe how interrupts are
- managed by the interrupt handling framework. This entails:
-
- #. Providing an interface to allow registration of a handler and
- specification of the routing model for a type of interrupt.
-
- #. Implementing support to hand control of an interrupt type to its
- registered handler when the interrupt is generated.
-
-Both aspects of interrupt management involve various components in the secure
-software stack spanning from EL3 to Secure-EL1. These components are described
-in the section `Software components`_. The framework stores information
-associated with each type of interrupt in the following data structure.
-
-.. code:: c
-
- typedef struct intr_type_desc {
- interrupt_type_handler_t handler;
- uint32_t flags;
- uint32_t scr_el3[2];
- } intr_type_desc_t;
-
-The ``flags`` field stores the routing model for the interrupt type in
-bits[1:0]. Bit[0] stores the routing model when execution is in the secure
-state. Bit[1] stores the routing model when execution is in the non-secure
-state. As mentioned in Section `Routing model`_, a value of ``0`` implies that
-the interrupt should be targeted to the FEL. A value of ``1`` implies that it
-should be targeted to EL3. The remaining bits are reserved and SBZ. The helper
-macro ``set_interrupt_rm_flag()`` should be used to set the bits in the
-``flags`` parameter.
-
-The ``scr_el3[2]`` field also stores the routing model but as a mapping of the
-model in the ``flags`` field to the corresponding bit in the ``SCR_EL3`` for each
-security state.
-
-The framework also depends upon the platform port to configure the interrupt
-controller to distinguish between secure and non-secure interrupts. The platform
-is expected to be aware of the secure devices present in the system and their
-associated interrupt numbers. It should configure the interrupt controller to
-enable the secure interrupts, ensure that their priority is always higher than
-the non-secure interrupts and target them to the primary CPU. It should also
-export the interface described in the `Porting Guide`_ to enable
-handling of interrupts.
-
-In the remainder of this document, for the sake of simplicity a Arm GICv2 system
-is considered and it is assumed that the FIQ signal is used to generate Secure-EL1
-interrupts and the IRQ signal is used to generate non-secure interrupts in either
-security state. EL3 interrupts are not considered.
-
-Software components
--------------------
-
-Roles and responsibilities for interrupt management are sub-divided between the
-following components of software running in EL3 and Secure-EL1. Each component is
-briefly described below.
-
-#. EL3 Runtime Firmware. This component is common to all ports of TF-A.
-
-#. Secure Payload Dispatcher (SPD) service. This service interfaces with the
- Secure Payload (SP) software which runs in Secure-EL1/Secure-EL0 and is
- responsible for switching execution between secure and non-secure states.
- A switch is triggered by a Secure Monitor Call and it uses the APIs
- exported by the Context management library to implement this functionality.
- Switching execution between the two security states is a requirement for
- interrupt management as well. This results in a significant dependency on
- the SPD service. TF-A implements an example Test Secure Payload Dispatcher
- (TSPD) service.
-
- An SPD service plugs into the EL3 runtime firmware and could be common to
- some ports of TF-A.
-
-#. Secure Payload (SP). On a production system, the Secure Payload corresponds
- to a Secure OS which runs in Secure-EL1/Secure-EL0. It interfaces with the
- SPD service to manage communication with non-secure software. TF-A
- implements an example secure payload called Test Secure Payload (TSP)
- which runs only in Secure-EL1.
-
- A Secure payload implementation could be common to some ports of TF-A,
- just like the SPD service.
-
-Interrupt registration
-----------------------
-
-This section describes in detail the role of each software component (see
-`Software components`_) during the registration of a handler for an interrupt
-type.
-
-EL3 runtime firmware
-~~~~~~~~~~~~~~~~~~~~
-
-This component declares the following prototype for a handler of an interrupt type.
-
-.. code:: c
-
- typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,
- uint32_t flags,
- void *handle,
- void *cookie);
-
-The ``id`` is parameter is reserved and could be used in the future for passing
-the interrupt id of the highest pending interrupt only if there is a foolproof
-way of determining the id. Currently it contains ``INTR_ID_UNAVAILABLE``.
-
-The ``flags`` parameter contains miscellaneous information as follows.
-
-#. Security state, bit[0]. This bit indicates the security state of the lower
- exception level when the interrupt was generated. A value of ``1`` means
- that it was in the non-secure state. A value of ``0`` indicates that it was
- in the secure state. This bit can be used by the handler to ensure that
- interrupt was generated and routed as per the routing model specified
- during registration.
-
-#. Reserved, bits[31:1]. The remaining bits are reserved for future use.
-
-The ``handle`` parameter points to the ``cpu_context`` structure of the current CPU
-for the security state specified in the ``flags`` parameter.
-
-Once the handler routine completes, execution will return to either the secure
-or non-secure state. The handler routine must return a pointer to
-``cpu_context`` structure of the current CPU for the target security state. On
-AArch64, this return value is currently ignored by the caller as the
-appropriate ``cpu_context`` to be used is expected to be set by the handler
-via the context management library APIs.
-A portable interrupt handler implementation must set the target context both in
-the structure pointed to by the returned pointer and via the context management
-library APIs. The handler should treat all error conditions as critical errors
-and take appropriate action within its implementation e.g. use assertion
-failures.
-
-The runtime firmware provides the following API for registering a handler for a
-particular type of interrupt. A Secure Payload Dispatcher service should use
-this API to register a handler for Secure-EL1 and optionally for non-secure
-interrupts. This API also requires the caller to specify the routing model for
-the type of interrupt.
-
-.. code:: c
-
- int32_t register_interrupt_type_handler(uint32_t type,
- interrupt_type_handler handler,
- uint64_t flags);
-
-The ``type`` parameter can be one of the three interrupt types listed above i.e.
-``INTR_TYPE_S_EL1``, ``INTR_TYPE_NS`` & ``INTR_TYPE_EL3``. The ``flags`` parameter
-is as described in Section 2.
-
-The function will return ``0`` upon a successful registration. It will return
-``-EALREADY`` in case a handler for the interrupt type has already been
-registered. If the ``type`` is unrecognised or the ``flags`` or the ``handler`` are
-invalid it will return ``-EINVAL``.
-
-Interrupt routing is governed by the configuration of the ``SCR_EL3.FIQ/IRQ`` bits
-prior to entry into a lower exception level in either security state. The
-context management library maintains a copy of the ``SCR_EL3`` system register for
-each security state in the ``cpu_context`` structure of each CPU. It exports the
-following APIs to let EL3 Runtime Firmware program and retrieve the routing
-model for each security state for the current CPU. The value of ``SCR_EL3`` stored
-in the ``cpu_context`` is used by the ``el3_exit()`` function to program the
-``SCR_EL3`` register prior to returning from the EL3 exception level.
-
-.. code:: c
-
- uint32_t cm_get_scr_el3(uint32_t security_state);
- void cm_write_scr_el3_bit(uint32_t security_state,
- uint32_t bit_pos,
- uint32_t value);
-
-``cm_get_scr_el3()`` returns the value of the ``SCR_EL3`` register for the specified
-security state of the current CPU. ``cm_write_scr_el3()`` writes a ``0`` or ``1`` to
-the bit specified by ``bit_pos``. ``register_interrupt_type_handler()`` invokes
-``set_routing_model()`` API which programs the ``SCR_EL3`` according to the routing
-model using the ``cm_get_scr_el3()`` and ``cm_write_scr_el3_bit()`` APIs.
-
-It is worth noting that in the current implementation of the framework, the EL3
-runtime firmware is responsible for programming the routing model. The SPD is
-responsible for ensuring that the routing model has been adhered to upon
-receiving an interrupt.
-
-.. _spd-int-registration:
-
-Secure payload dispatcher
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A SPD service is responsible for determining and maintaining the interrupt
-routing model supported by itself and the Secure Payload. It is also responsible
-for ferrying interrupts between secure and non-secure software depending upon
-the routing model. It could determine the routing model at build time or at
-runtime. It must use this information to register a handler for each interrupt
-type using the ``register_interrupt_type_handler()`` API in EL3 runtime firmware.
-
-If the routing model is not known to the SPD service at build time, then it must
-be provided by the SP as the result of its initialisation. The SPD should
-program the routing model only after SP initialisation has completed e.g. in the
-SPD initialisation function pointed to by the ``bl32_init`` variable.
-
-The SPD should determine the mechanism to pass control to the Secure Payload
-after receiving an interrupt from the EL3 runtime firmware. This information
-could either be provided to the SPD service at build time or by the SP at
-runtime.
-
-Test secure payload dispatcher behavior
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Note:** where this document discusses ``TSP_NS_INTR_ASYNC_PREEMPT`` as being
-``1``, the same results also apply when ``EL3_EXCEPTION_HANDLING`` is ``1``.
-
-The TSPD only handles Secure-EL1 interrupts and is provided with the following
-routing model at build time.
-
-- Secure-EL1 interrupts are routed to EL3 when execution is in non-secure
- state and are routed to the FEL when execution is in the secure state
- i.e **CSS=0, TEL3=0** & **CSS=1, TEL3=1** for Secure-EL1 interrupts
-
-- When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is zero, the default routing
- model is used for non-secure interrupts. They are routed to the FEL in
- either security state i.e **CSS=0, TEL3=0** & **CSS=1, TEL3=0** for
- Non-secure interrupts.
-
-- When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is defined to 1, then the
- non secure interrupts are routed to EL3 when execution is in secure state
- i.e **CSS=0, TEL3=1** for non-secure interrupts. This effectively preempts
- Secure-EL1. The default routing model is used for non secure interrupts in
- non-secure state. i.e **CSS=1, TEL3=0**.
-
-It performs the following actions in the ``tspd_init()`` function to fulfill the
-requirements mentioned earlier.
-
-#. It passes control to the Test Secure Payload to perform its
- initialisation. The TSP provides the address of the vector table
- ``tsp_vectors`` in the SP which also includes the handler for Secure-EL1
- interrupts in the ``sel1_intr_entry`` field. The TSPD passes control to the TSP at
- this address when it receives a Secure-EL1 interrupt.
-
- The handover agreement between the TSP and the TSPD requires that the TSPD
- masks all interrupts (``PSTATE.DAIF`` bits) when it calls
- ``tsp_sel1_intr_entry()``. The TSP has to preserve the callee saved general
- purpose, SP_EL1/Secure-EL0, LR, VFP and system registers. It can use
- ``x0-x18`` to enable its C runtime.
-
-#. The TSPD implements a handler function for Secure-EL1 interrupts. This
- function is registered with the EL3 runtime firmware using the
- ``register_interrupt_type_handler()`` API as follows
-
- .. code:: c
-
- /* Forward declaration */
- interrupt_type_handler tspd_secure_el1_interrupt_handler;
- int32_t rc, flags = 0;
- set_interrupt_rm_flag(flags, NON_SECURE);
- rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
- tspd_secure_el1_interrupt_handler,
- flags);
- if (rc)
- panic();
-
-#. When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is defined to 1, the TSPD
- implements a handler function for non-secure interrupts. This function is
- registered with the EL3 runtime firmware using the
- ``register_interrupt_type_handler()`` API as follows
-
- .. code:: c
-
- /* Forward declaration */
- interrupt_type_handler tspd_ns_interrupt_handler;
- int32_t rc, flags = 0;
- set_interrupt_rm_flag(flags, SECURE);
- rc = register_interrupt_type_handler(INTR_TYPE_NS,
- tspd_ns_interrupt_handler,
- flags);
- if (rc)
- panic();
-
-.. _sp-int-registration:
-
-Secure payload
-~~~~~~~~~~~~~~
-
-A Secure Payload must implement an interrupt handling framework at Secure-EL1
-(Secure-EL1 IHF) to support its chosen interrupt routing model. Secure payload
-execution will alternate between the below cases.
-
-#. In the code where IRQ, FIQ or both interrupts are enabled, if an interrupt
- type is targeted to the FEL, then it will be routed to the Secure-EL1
- exception vector table. This is defined as the **asynchronous mode** of
- handling interrupts. This mode applies to both Secure-EL1 and non-secure
- interrupts.
-
-#. In the code where both interrupts are disabled, if an interrupt type is
- targeted to the FEL, then execution will eventually migrate to the
- non-secure state. Any non-secure interrupts will be handled as described
- in the routing model where **CSS=1 and TEL3=0**. Secure-EL1 interrupts
- will be routed to EL3 (as per the routing model where **CSS=1 and
- TEL3=1**) where the SPD service will hand them to the SP. This is defined
- as the **synchronous mode** of handling interrupts.
-
-The interrupt handling framework implemented by the SP should support one or
-both these interrupt handling models depending upon the chosen routing model.
-
-The following list briefly describes how the choice of a valid routing model
-(see `Valid routing models`_) effects the implementation of the Secure-EL1
-IHF. If the choice of the interrupt routing model is not known to the SPD
-service at compile time, then the SP should pass this information to the SPD
-service at runtime during its initialisation phase.
-
-As mentioned earlier, an Arm GICv2 system is considered and it is assumed that
-the FIQ signal is used to generate Secure-EL1 interrupts and the IRQ signal
-is used to generate non-secure interrupts in either security state.
-
-Secure payload IHF design w.r.t secure-EL1 interrupts
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-#. **CSS=0, TEL3=0**. If ``PSTATE.F=0``, Secure-EL1 interrupts will be
- triggered at one of the Secure-EL1 FIQ exception vectors. The Secure-EL1
- IHF should implement support for handling FIQ interrupts asynchronously.
-
- If ``PSTATE.F=1`` then Secure-EL1 interrupts will be handled as per the
- synchronous interrupt handling model. The SP could implement this scenario
- by exporting a separate entrypoint for Secure-EL1 interrupts to the SPD
- service during the registration phase. The SPD service would also need to
- know the state of the system, general purpose and the ``PSTATE`` registers
- in which it should arrange to return execution to the SP. The SP should
- provide this information in an implementation defined way during the
- registration phase if it is not known to the SPD service at build time.
-
-#. **CSS=1, TEL3=1**. Interrupts are routed to EL3 when execution is in
- non-secure state. They should be handled through the synchronous interrupt
- handling model as described in 1. above.
-
-#. **CSS=0, TEL3=1**. Secure-EL1 interrupts are routed to EL3 when execution
- is in secure state. They will not be visible to the SP. The ``PSTATE.F`` bit
- in Secure-EL1/Secure-EL0 will not mask FIQs. The EL3 runtime firmware will
- call the handler registered by the SPD service for Secure-EL1 interrupts.
- Secure-EL1 IHF should then handle all Secure-EL1 interrupt through the
- synchronous interrupt handling model described in 1. above.
-
-Secure payload IHF design w.r.t non-secure interrupts
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-#. **CSS=0, TEL3=0**. If ``PSTATE.I=0``, non-secure interrupts will be
- triggered at one of the Secure-EL1 IRQ exception vectors . The Secure-EL1
- IHF should co-ordinate with the SPD service to transfer execution to the
- non-secure state where the interrupt should be handled e.g the SP could
- allocate a function identifier to issue a SMC64 or SMC32 to the SPD
- service which indicates that the SP execution has been preempted by a
- non-secure interrupt. If this function identifier is not known to the SPD
- service at compile time then the SP could provide it during the
- registration phase.
-
- If ``PSTATE.I=1`` then the non-secure interrupt will pend until execution
- resumes in the non-secure state.
-
-#. **CSS=0, TEL3=1**. Non-secure interrupts are routed to EL3. They will not
- be visible to the SP. The ``PSTATE.I`` bit in Secure-EL1/Secure-EL0 will
- have not effect. The SPD service should register a non-secure interrupt
- handler which should save the SP state correctly and resume execution in
- the non-secure state where the interrupt will be handled. The Secure-EL1
- IHF does not need to take any action.
-
-#. **CSS=1, TEL3=0**. Non-secure interrupts are handled in the FEL in
- non-secure state (EL1/EL2) and are not visible to the SP. This routing
- model does not affect the SP behavior.
-
-A Secure Payload must also ensure that all Secure-EL1 interrupts are correctly
-configured at the interrupt controller by the platform port of the EL3 runtime
-firmware. It should configure any additional Secure-EL1 interrupts which the EL3
-runtime firmware is not aware of through its platform port.
-
-Test secure payload behavior
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The routing model for Secure-EL1 and non-secure interrupts chosen by the TSP is
-described in Section `Secure Payload Dispatcher`__. It is known to the TSPD
-service at build time.
-
-.. __: #spd-int-registration
-
-The TSP implements an entrypoint (``tsp_sel1_intr_entry()``) for handling Secure-EL1
-interrupts taken in non-secure state and routed through the TSPD service
-(synchronous handling model). It passes the reference to this entrypoint via
-``tsp_vectors`` to the TSPD service.
-
-The TSP also replaces the default exception vector table referenced through the
-``early_exceptions`` variable, with a vector table capable of handling FIQ and IRQ
-exceptions taken at the same (Secure-EL1) exception level. This table is
-referenced through the ``tsp_exceptions`` variable and programmed into the
-VBAR_EL1. It caters for the asynchronous handling model.
-
-The TSP also programs the Secure Physical Timer in the Arm Generic Timer block
-to raise a periodic interrupt (every half a second) for the purpose of testing
-interrupt management across all the software components listed in `Software
-components`_.
-
-Interrupt handling
-------------------
-
-This section describes in detail the role of each software component (see
-Section `Software components`_) in handling an interrupt of a particular type.
-
-EL3 runtime firmware
-~~~~~~~~~~~~~~~~~~~~
-
-The EL3 runtime firmware populates the IRQ and FIQ exception vectors referenced
-by the ``runtime_exceptions`` variable as follows.
-
-#. IRQ and FIQ exceptions taken from the current exception level with
- ``SP_EL0`` or ``SP_EL3`` are reported as irrecoverable error conditions. As
- mentioned earlier, EL3 runtime firmware always executes with the
- ``PSTATE.I`` and ``PSTATE.F`` bits set.
-
-#. The following text describes how the IRQ and FIQ exceptions taken from a
- lower exception level using AArch64 or AArch32 are handled.
-
-When an interrupt is generated, the vector for each interrupt type is
-responsible for:
-
-#. Saving the entire general purpose register context (x0-x30) immediately
- upon exception entry. The registers are saved in the per-cpu ``cpu_context``
- data structure referenced by the ``SP_EL3``\ register.
-
-#. Saving the ``ELR_EL3``, ``SP_EL0`` and ``SPSR_EL3`` system registers in the
- per-cpu ``cpu_context`` data structure referenced by the ``SP_EL3`` register.
-
-#. Switching to the C runtime stack by restoring the ``CTX_RUNTIME_SP`` value
- from the per-cpu ``cpu_context`` data structure in ``SP_EL0`` and
- executing the ``msr spsel, #0`` instruction.
-
-#. Determining the type of interrupt. Secure-EL1 interrupts will be signaled
- at the FIQ vector. Non-secure interrupts will be signaled at the IRQ
- vector. The platform should implement the following API to determine the
- type of the pending interrupt.
-
- .. code:: c
-
- uint32_t plat_ic_get_interrupt_type(void);
-
- It should return either ``INTR_TYPE_S_EL1`` or ``INTR_TYPE_NS``.
-
-#. Determining the handler for the type of interrupt that has been generated.
- The following API has been added for this purpose.
-
- .. code:: c
-
- interrupt_type_handler get_interrupt_type_handler(uint32_t interrupt_type);
-
- It returns the reference to the registered handler for this interrupt
- type. The ``handler`` is retrieved from the ``intr_type_desc_t`` structure as
- described in Section 2. ``NULL`` is returned if no handler has been
- registered for this type of interrupt. This scenario is reported as an
- irrecoverable error condition.
-
-#. Calling the registered handler function for the interrupt type generated.
- The ``id`` parameter is set to ``INTR_ID_UNAVAILABLE`` currently. The id along
- with the current security state and a reference to the ``cpu_context_t``
- structure for the current security state are passed to the handler function
- as its arguments.
-
- The handler function returns a reference to the per-cpu ``cpu_context_t``
- structure for the target security state.
-
-#. Calling ``el3_exit()`` to return from EL3 into a lower exception level in
- the security state determined by the handler routine. The ``el3_exit()``
- function is responsible for restoring the register context from the
- ``cpu_context_t`` data structure for the target security state.
-
-Secure payload dispatcher
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Interrupt entry
-^^^^^^^^^^^^^^^
-
-The SPD service begins handling an interrupt when the EL3 runtime firmware calls
-the handler function for that type of interrupt. The SPD service is responsible
-for the following:
-
-#. Validating the interrupt. This involves ensuring that the interrupt was
- generated according to the interrupt routing model specified by the SPD
- service during registration. It should use the security state of the
- exception level (passed in the ``flags`` parameter of the handler) where
- the interrupt was taken from to determine this. If the interrupt is not
- recognised then the handler should treat it as an irrecoverable error
- condition.
-
- An SPD service can register a handler for Secure-EL1 and/or Non-secure
- interrupts. A non-secure interrupt should never be routed to EL3 from
- from non-secure state. Also if a routing model is chosen where Secure-EL1
- interrupts are routed to S-EL1 when execution is in Secure state, then a
- S-EL1 interrupt should never be routed to EL3 from secure state. The handler
- could use the security state flag to check this.
-
-#. Determining whether a context switch is required. This depends upon the
- routing model and interrupt type. For non secure and S-EL1 interrupt,
- if the security state of the execution context where the interrupt was
- generated is not the same as the security state required for handling
- the interrupt, a context switch is required. The following 2 cases
- require a context switch from secure to non-secure or vice-versa:
-
- #. A Secure-EL1 interrupt taken from the non-secure state should be
- routed to the Secure Payload.
-
- #. A non-secure interrupt taken from the secure state should be routed
- to the last known non-secure exception level.
-
- The SPD service must save the system register context of the current
- security state. It must then restore the system register context of the
- target security state. It should use the ``cm_set_next_eret_context()`` API
- to ensure that the next ``cpu_context`` to be restored is of the target
- security state.
-
- If the target state is secure then execution should be handed to the SP as
- per the synchronous interrupt handling model it implements. A Secure-EL1
- interrupt can be routed to EL3 while execution is in the SP. This implies
- that SP execution can be preempted while handling an interrupt by a
- another higher priority Secure-EL1 interrupt or a EL3 interrupt. The SPD
- service should be able to handle this preemption or manage secure interrupt
- priorities before handing control to the SP.
-
-#. Setting the return value of the handler to the per-cpu ``cpu_context`` if
- the interrupt has been successfully validated and ready to be handled at a
- lower exception level.
-
-The routing model allows non-secure interrupts to interrupt Secure-EL1 when in
-secure state if it has been configured to do so. The SPD service and the SP
-should implement a mechanism for routing these interrupts to the last known
-exception level in the non-secure state. The former should save the SP context,
-restore the non-secure context and arrange for entry into the non-secure state
-so that the interrupt can be handled.
-
-Interrupt exit
-^^^^^^^^^^^^^^
-
-When the Secure Payload has finished handling a Secure-EL1 interrupt, it could
-return control back to the SPD service through a SMC32 or SMC64. The SPD service
-should handle this secure monitor call so that execution resumes in the
-exception level and the security state from where the Secure-EL1 interrupt was
-originally taken.
-
-Test secure payload dispatcher Secure-EL1 interrupt handling
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The example TSPD service registers a handler for Secure-EL1 interrupts taken
-from the non-secure state. During execution in S-EL1, the TSPD expects that the
-Secure-EL1 interrupts are handled in S-EL1 by TSP. Its handler
-``tspd_secure_el1_interrupt_handler()`` expects only to be invoked for Secure-EL1
-originating from the non-secure state. It takes the following actions upon being
-invoked.
-
-#. It uses the security state provided in the ``flags`` parameter to ensure
- that the secure interrupt originated from the non-secure state. It asserts
- if this is not the case.
-
-#. It saves the system register context for the non-secure state by calling
- ``cm_el1_sysregs_context_save(NON_SECURE);``.
-
-#. It sets the ``ELR_EL3`` system register to ``tsp_sel1_intr_entry`` and sets the
- ``SPSR_EL3.DAIF`` bits in the secure CPU context. It sets ``x0`` to
- ``TSP_HANDLE_SEL1_INTR_AND_RETURN``. If the TSP was preempted earlier by a non
- secure interrupt during ``yielding`` SMC processing, save the registers that
- will be trashed, which is the ``ELR_EL3`` and ``SPSR_EL3``, in order to be able
- to re-enter TSP for Secure-EL1 interrupt processing. It does not need to
- save any other secure context since the TSP is expected to preserve it
- (see section `Test secure payload dispatcher behavior`_).
-
-#. It restores the system register context for the secure state by calling
- ``cm_el1_sysregs_context_restore(SECURE);``.
-
-#. It ensures that the secure CPU context is used to program the next
- exception return from EL3 by calling ``cm_set_next_eret_context(SECURE);``.
-
-#. It returns the per-cpu ``cpu_context`` to indicate that the interrupt can
- now be handled by the SP. ``x1`` is written with the value of ``elr_el3``
- register for the non-secure state. This information is used by the SP for
- debugging purposes.
-
-The figure below describes how the interrupt handling is implemented by the TSPD
-when a Secure-EL1 interrupt is generated when execution is in the non-secure
-state.
-
-|Image 1|
-
-The TSP issues an SMC with ``TSP_HANDLED_S_EL1_INTR`` as the function identifier to
-signal completion of interrupt handling.
-
-The TSPD service takes the following actions in ``tspd_smc_handler()`` function
-upon receiving an SMC with ``TSP_HANDLED_S_EL1_INTR`` as the function identifier:
-
-#. It ensures that the call originated from the secure state otherwise
- execution returns to the non-secure state with ``SMC_UNK`` in ``x0``.
-
-#. It restores the saved ``ELR_EL3`` and ``SPSR_EL3`` system registers back to
- the secure CPU context (see step 3 above) in case the TSP had been preempted
- by a non secure interrupt earlier.
-
-#. It restores the system register context for the non-secure state by
- calling ``cm_el1_sysregs_context_restore(NON_SECURE)``.
-
-#. It ensures that the non-secure CPU context is used to program the next
- exception return from EL3 by calling ``cm_set_next_eret_context(NON_SECURE)``.
-
-#. ``tspd_smc_handler()`` returns a reference to the non-secure ``cpu_context``
- as the return value.
-
-Test secure payload dispatcher non-secure interrupt handling
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The TSP in Secure-EL1 can be preempted by a non-secure interrupt during
-``yielding`` SMC processing or by a higher priority EL3 interrupt during
-Secure-EL1 interrupt processing. When ``EL3_EXCEPTION_HANDLING`` is ``0``, only
-non-secure interrupts can cause preemption of TSP since there are no EL3
-interrupts in the system. With ``EL3_EXCEPTION_HANDLING=1`` however, any EL3
-interrupt may preempt Secure execution.
-
-It should be noted that while TSP is preempted, the TSPD only allows entry into
-the TSP either for Secure-EL1 interrupt handling or for resuming the preempted
-``yielding`` SMC in response to the ``TSP_FID_RESUME`` SMC from the normal world.
-(See Section `Implication of preempted SMC on Non-Secure Software`_).
-
-The non-secure interrupt triggered in Secure-EL1 during ``yielding`` SMC
-processing can be routed to either EL3 or Secure-EL1 and is controlled by build
-option ``TSP_NS_INTR_ASYNC_PREEMPT`` (see Section `Test secure payload
-dispatcher behavior`_). If the build option is set, the TSPD will set the
-routing model for the non-secure interrupt to be routed to EL3 from secure state
-i.e. **TEL3=1, CSS=0** and registers ``tspd_ns_interrupt_handler()`` as the
-non-secure interrupt handler. The ``tspd_ns_interrupt_handler()`` on being
-invoked ensures that the interrupt originated from the secure state and disables
-routing of non-secure interrupts from secure state to EL3. This is to prevent
-further preemption (by a non-secure interrupt) when TSP is reentered for
-handling Secure-EL1 interrupts that triggered while execution was in the normal
-world. The ``tspd_ns_interrupt_handler()`` then invokes
-``tspd_handle_sp_preemption()`` for further handling.
-
-If the ``TSP_NS_INTR_ASYNC_PREEMPT`` build option is zero (default), the default
-routing model for non-secure interrupt in secure state is in effect
-i.e. **TEL3=0, CSS=0**. During ``yielding`` SMC processing, the IRQ
-exceptions are unmasked i.e. ``PSTATE.I=0``, and a non-secure interrupt will
-trigger at Secure-EL1 IRQ exception vector. The TSP saves the general purpose
-register context and issues an SMC with ``TSP_PREEMPTED`` as the function
-identifier to signal preemption of TSP. The TSPD SMC handler,
-``tspd_smc_handler()``, ensures that the SMC call originated from the
-secure state otherwise execution returns to the non-secure state with
-``SMC_UNK`` in ``x0``. It then invokes ``tspd_handle_sp_preemption()`` for
-further handling.
-
-The ``tspd_handle_sp_preemption()`` takes the following actions upon being
-invoked:
-
-#. It saves the system register context for the secure state by calling
- ``cm_el1_sysregs_context_save(SECURE)``.
-
-#. It restores the system register context for the non-secure state by
- calling ``cm_el1_sysregs_context_restore(NON_SECURE)``.
-
-#. It ensures that the non-secure CPU context is used to program the next
- exception return from EL3 by calling ``cm_set_next_eret_context(NON_SECURE)``.
-
-#. ``SMC_PREEMPTED`` is set in x0 and return to non secure state after
- restoring non secure context.
-
-The Normal World is expected to resume the TSP after the ``yielding`` SMC
-preemption by issuing an SMC with ``TSP_FID_RESUME`` as the function identifier
-(see section `Implication of preempted SMC on Non-Secure Software`_). The TSPD
-service takes the following actions in ``tspd_smc_handler()`` function upon
-receiving this SMC:
-
-#. It ensures that the call originated from the non secure state. An
- assertion is raised otherwise.
-
-#. Checks whether the TSP needs a resume i.e check if it was preempted. It
- then saves the system register context for the non-secure state by calling
- ``cm_el1_sysregs_context_save(NON_SECURE)``.
-
-#. Restores the secure context by calling
- ``cm_el1_sysregs_context_restore(SECURE)``
-
-#. It ensures that the secure CPU context is used to program the next
- exception return from EL3 by calling ``cm_set_next_eret_context(SECURE)``.
-
-#. ``tspd_smc_handler()`` returns a reference to the secure ``cpu_context`` as the
- return value.
-
-The figure below describes how the TSP/TSPD handle a non-secure interrupt when
-it is generated during execution in the TSP with ``PSTATE.I`` = 0 when the
-``TSP_NS_INTR_ASYNC_PREEMPT`` build flag is 0.
-
-|Image 2|
-
-Secure payload
-~~~~~~~~~~~~~~
-
-The SP should implement one or both of the synchronous and asynchronous
-interrupt handling models depending upon the interrupt routing model it has
-chosen (as described in section `Secure Payload`__).
-
-.. __: #sp-int-registration
-
-In the synchronous model, it should begin handling a Secure-EL1 interrupt after
-receiving control from the SPD service at an entrypoint agreed upon during build
-time or during the registration phase. Before handling the interrupt, the SP
-should save any Secure-EL1 system register context which is needed for resuming
-normal execution in the SP later e.g. ``SPSR_EL1``, ``ELR_EL1``. After handling
-the interrupt, the SP could return control back to the exception level and
-security state where the interrupt was originally taken from. The SP should use
-an SMC32 or SMC64 to ask the SPD service to do this.
-
-In the asynchronous model, the Secure Payload is responsible for handling
-non-secure and Secure-EL1 interrupts at the IRQ and FIQ vectors in its exception
-vector table when ``PSTATE.I`` and ``PSTATE.F`` bits are 0. As described earlier,
-when a non-secure interrupt is generated, the SP should coordinate with the SPD
-service to pass control back to the non-secure state in the last known exception
-level. This will allow the non-secure interrupt to be handled in the non-secure
-state.
-
-Test secure payload behavior
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The TSPD hands control of a Secure-EL1 interrupt to the TSP at the
-``tsp_sel1_intr_entry()``. The TSP handles the interrupt while ensuring that the
-handover agreement described in Section `Test secure payload dispatcher
-behavior`_ is maintained. It updates some statistics by calling
-``tsp_update_sync_sel1_intr_stats()``. It then calls
-``tsp_common_int_handler()`` which.
-
-#. Checks whether the interrupt is the secure physical timer interrupt. It
- uses the platform API ``plat_ic_get_pending_interrupt_id()`` to get the
- interrupt number. If it is not the secure physical timer interrupt, then
- that means that a higher priority interrupt has preempted it. Invoke
- ``tsp_handle_preemption()`` to handover control back to EL3 by issuing
- an SMC with ``TSP_PREEMPTED`` as the function identifier.
-
-#. Handles the secure timer interrupt interrupt by acknowledging it using the
- ``plat_ic_acknowledge_interrupt()`` platform API, calling
- ``tsp_generic_timer_handler()`` to reprogram the secure physical generic
- timer and calling the ``plat_ic_end_of_interrupt()`` platform API to signal
- end of interrupt processing.
-
-The TSP passes control back to the TSPD by issuing an SMC64 with
-``TSP_HANDLED_S_EL1_INTR`` as the function identifier.
-
-The TSP handles interrupts under the asynchronous model as follows.
-
-#. Secure-EL1 interrupts are handled by calling the ``tsp_common_int_handler()``
- function. The function has been described above.
-
-#. Non-secure interrupts are handled by calling the ``tsp_common_int_handler()``
- function which ends up invoking ``tsp_handle_preemption()`` and issuing an
- SMC64 with ``TSP_PREEMPTED`` as the function identifier. Execution resumes at
- the instruction that follows this SMC instruction when the TSPD hands control
- to the TSP in response to an SMC with ``TSP_FID_RESUME`` as the function
- identifier from the non-secure state (see section `Test secure payload
- dispatcher non-secure interrupt handling`_).
-
-Other considerations
---------------------
-
-Implication of preempted SMC on Non-Secure Software
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A ``yielding`` SMC call to Secure payload can be preempted by a non-secure
-interrupt and the execution can return to the non-secure world for handling
-the interrupt (For details on ``yielding`` SMC refer `SMC calling convention`_).
-In this case, the SMC call has not completed its execution and the execution
-must return back to the secure payload to resume the preempted SMC call.
-This can be achieved by issuing an SMC call which instructs to resume the
-preempted SMC.
-
-A ``fast`` SMC cannot be preempted and hence this case will not happen for
-a fast SMC call.
-
-In the Test Secure Payload implementation, ``TSP_FID_RESUME`` is designated
-as the resume SMC FID. It is important to note that ``TSP_FID_RESUME`` is a
-``yielding`` SMC which means it too can be be preempted. The typical non
-secure software sequence for issuing a ``yielding`` SMC would look like this,
-assuming ``P.STATE.I=0`` in the non secure state :
-
-.. code:: c
-
- int rc;
- rc = smc(TSP_YIELD_SMC_FID, ...); /* Issue a Yielding SMC call */
- /* The pending non-secure interrupt is handled by the interrupt handler
- and returns back here. */
- while (rc == SMC_PREEMPTED) { /* Check if the SMC call is preempted */
- rc = smc(TSP_FID_RESUME); /* Issue resume SMC call */
- }
-
-The ``TSP_YIELD_SMC_FID`` is any ``yielding`` SMC function identifier and the smc()
-function invokes a SMC call with the required arguments. The pending non-secure
-interrupt causes an IRQ exception and the IRQ handler registered at the
-exception vector handles the non-secure interrupt and returns. The return value
-from the SMC call is tested for ``SMC_PREEMPTED`` to check whether it is
-preempted. If it is, then the resume SMC call ``TSP_FID_RESUME`` is issued. The
-return value of the SMC call is tested again to check if it is preempted.
-This is done in a loop till the SMC call succeeds or fails. If a ``yielding``
-SMC is preempted, until it is resumed using ``TSP_FID_RESUME`` SMC and
-completed, the current TSPD prevents any other SMC call from re-entering
-TSP by returning ``SMC_UNK`` error.
-
---------------
-
-*Copyright (c) 2014-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _Porting Guide: ./porting-guide.rst
-.. _SMC calling convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
-
-.. |Image 1| image:: diagrams/sec-int-handling.png?raw=true
-.. |Image 2| image:: diagrams/non-sec-int-handling.png?raw=true
--- /dev/null
+Trusted Firmware-A maintainers
+==============================
+
+Trusted Firmware-A (TF-A) is an Arm maintained project. All contributions are
+ultimately merged by the maintainers listed below. Technical ownership of some
+parts of the codebase is delegated to the sub-maintainers listed below. An
+acknowledgement from these sub-maintainers may be required before the
+maintainers merge a contribution.
+
+Main maintainers
+----------------
+:G: `danh-arm`_
+:G: `dp-arm`_
+:G: `soby-mathew`_
+
+Allwinner ARMv8 platform port
+-----------------------------
+:G: `Andre-ARM`_
+:G: `smaeul`_
+:F: docs/plat/allwinner.rst
+:F: plat/allwinner/
+:F: drivers/allwinner/
+
+Amlogic Meson S905 (GXBB) platform port
+---------------------------------------
+:G: `Andre-ARM`_
+:F: docs/plat/meson-gxbb.rst
+:F: drivers/meson/
+:F: plat/meson/gxbb/
+
+Amlogic Meson S905x (GXL) platform port
+---------------------------------------
+:G: `remi-triplefault`_
+:F: docs/plat/meson-gxl.rst
+:F: drivers/meson/gxl
+:F: plat/meson/gxl/
+
+Armv7-A architecture port
+-------------------------
+:G: `etienne-lms`_
+
+Arm System Guidance for Infrastructure / Mobile FVP platforms
+-------------------------------------------------------------
+:G: `npoushin`_
+:G: `thomas-arm`_
+:F: plat/arm/css/sgi/
+:F: plat/arm/css/sgm/
+:F: plat/arm/board/sgi575/
+:F: plat/arm/board/sgm775/
+
+Console API framework
+---------------------
+:G: `jwerner-chromium`_
+:F: drivers/console/
+:F: include/drivers/console.h
+:F: plat/common/aarch64/crash_console_helpers.S
+
+coreboot support libraries
+--------------------------
+:G: `jwerner-chromium`_
+:F: drivers/coreboot/
+:F: include/drivers/coreboot/
+:F: include/lib/coreboot.h
+:F: lib/coreboot/
+
+eMMC/UFS drivers
+----------------
+:G: `hzhuang1`_
+:F: drivers/partition/
+:F: drivers/synopsys/emmc/
+:F: drivers/synopsys/ufs/
+:F: drivers/ufs/
+:F: include/drivers/dw_ufs.h
+:F: include/drivers/ufs.h
+:F: include/drivers/synopsys/dw_mmc.h
+
+HiSilicon HiKey and HiKey960 platform ports
+-------------------------------------------
+:G: `hzhuang1`_
+:F: docs/plat/hikey.rst
+:F: docs/plat/hikey960.rst
+:F: plat/hisilicon/hikey/
+:F: plat/hisilicon/hikey960/
+
+HiSilicon Poplar platform port
+------------------------------
+:G: `shawnguo2`_
+:F: docs/plat/poplar.rst
+:F: plat/hisilicon/poplar/
+
+Intel SocFPGA platform ports
+----------------------------
+:G: `thloh85-intel`
+:F: plat/intel/soc
+
+MediaTek platform ports
+-----------------------
+:G: `mtk09422`_
+:F: plat/mediatek/
+
+Marvell platform ports and SoC drivers
+--------------------------------------
+:G: `kostapr`_
+:F: docs/marvell/
+:F: plat/marvell/
+:F: drivers/marvell/
+:F: tools/marvell/
+
+NVidia platform ports
+---------------------
+:G: `vwadekar`_
+:F: docs/plat/nvidia-tegra.rst
+:F: include/lib/cpus/aarch64/denver.h
+:F: lib/cpus/aarch64/denver.S
+:F: plat/nvidia/
+
+NXP QorIQ Layerscape platform ports
+-----------------------------------
+:G: `qoriq-open-source`_
+:F: docs/plat/ls1043a.rst
+:F: plat/layerscape/
+
+NXP i.MX 7 WaRP7 platform port and SoC drivers
+----------------------------------------------
+:G: `bryanodonoghue`_
+:G: `niej`_
+:F: docs/plat/warp7.rst
+:F: plat/imx/common/
+:F: plat/imx/imx7/
+:F: drivers/imx/timer/
+:F: drivers/imx/uart/
+:F: drivers/imx/usdhc/
+
+NXP i.MX 8 platform port
+------------------------
+:G: `Anson-Huang`_
+:F: docs/plat/imx8.rst
+:F: plat/imx/
+
+NXP i.MX8M platform port
+------------------------
+:G: `JackyBai`_
+:F: doc/plat/imx8m.rst
+:F: plat/imx/imx8m/
+
+OP-TEE dispatcher
+-----------------
+:G: `jenswi-linaro`_
+:F: docs/spd/optee-dispatcher.rst
+:F: services/spd/opteed/
+
+QEMU platform port
+------------------
+:G: `jenswi-linaro`_
+:F: docs/plat/qemu.rst
+:F: plat/qemu/
+
+Raspberry Pi 3 platform port
+----------------------------
+:G: `grandpaul`_
+:F: docs/plat/rpi3.rst
+:F: plat/rpi3/
+:F: drivers/rpi3/
+:F: include/drivers/rpi3/
+
+Renesas rcar-gen3 platform port
+-------------------------------
+:G: `ldts`_
+:G: `marex`_
+:F: docs/plat/rcar-gen3.rst
+:F: plat/renesas/rcar
+:F: drivers/renesas/rcar
+:F: tools/renesas/rcar_layout_create
+
+RockChip platform port
+----------------------
+:G: `TonyXie06`_
+:G: `rockchip-linux`_
+:G: `mmind`_
+:F: plat/rockchip/
+
+STM32MP1 platform port
+----------------------
+:G: `Yann-lms`_
+:F: docs/plat/stm32mp1.rst
+:F: drivers/st/
+:F: fdts/stm32\*
+:F: include/drivers/st/
+:F: include/dt-bindings/\*/stm32\*
+:F: plat/st/
+:F: tools/stm32image/
+
+Synquacer platform port
+-----------------------
+:G: `b49020`_
+:F: docs/plat/synquacer.rst
+:F: plat/socionext/synquacer/
+
+Texas Instruments platform port
+-------------------------------
+:G: `glneo`_
+:F: docs/plat/ti-k3.rst
+:F: plat/ti/
+
+TLK/Trusty secure payloads
+--------------------------
+:G: `vwadekar`_
+:F: docs/spd/tlk-dispatcher.rst
+:F: docs/spd/trusty-dispatcher.rst
+:F: include/bl32/payloads/tlk.h
+:F: services/spd/tlkd/
+:F: services/spd/trusty/
+
+UniPhier platform port
+----------------------
+:G: `masahir0y`_
+:F: docs/plat/socionext-uniphier.rst
+:F: plat/socionext/uniphier/
+
+Xilinx platform port
+--------------------
+:G: `sivadur`_
+:F: docs/plat/xilinx-zynqmp.rst
+:F: plat/xilinx/
+
+.. _Andre-ARM: https://github.com/Andre-ARM
+.. _Anson-Huang: https://github.com/Anson-Huang
+.. _bryanodonoghue: https://github.com/bryanodonoghue
+.. _b49020: https://github.com/b49020
+.. _danh-arm: https://github.com/danh-arm
+.. _dp-arm: https://github.com/dp-arm
+.. _etienne-lms: https://github.com/etienne-lms
+.. _glneo: https://github.com/glneo
+.. _hzhuang1: https://github.com/hzhuang1
+.. _JackyBai: https://github.com/JackyBai
+.. _jenswi-linaro: https://github.com/jenswi-linaro
+.. _ldts: https://github.com/ldts
+.. _marex: https://github.com/marex
+.. _niej: https://github.com/niej
+.. _kostapr: https://github.com/kostapr
+.. _masahir0y: https://github.com/masahir0y
+.. _mmind: https://github.com/mmind
+.. _mtk09422: https://github.com/mtk09422
+.. _npoushin: https://github.com/npoushin
+.. _qoriq-open-source: https://github.com/qoriq-open-source
+.. _remi-triplefault: https://github.com/repk
+.. _rockchip-linux: https://github.com/rockchip-linux
+.. _shawnguo2: https://github.com/shawnguo2
+.. _sivadur: https://github.com/sivadur
+.. _smaeul: https://github.com/smaeul
+.. _soby-mathew: https://github.com/soby-mathew
+.. _thomas-arm: https://github.com/thomas-arm
+.. _TonyXie06: https://github.com/TonyXie06
+.. _vwadekar: https://github.com/vwadekar
+.. _Yann-lms: https://github.com/Yann-lms
+.. _grandpaul: https://github.com/grandpaul
+.. _jwerner-chromium: https://github.com/jwerner-chromium
+++ /dev/null
-TF-A Build Instructions
-======================
-
-This section describes how to compile the ARM Trusted Firmware (TF-A) project for Marvell's platforms.
-
-Build Instructions
-------------------
-(1) Set the cross compiler::
-
- > export CROSS_COMPILE=/path/to/toolchain/aarch64-linux-gnu-
-
-(2) Set path for FIP images:
-
- Set U-Boot image path (relatively to TF-A root or absolute path)::
-
- > export BL33=path/to/u-boot.bin
-
- For example: if U-Boot project (and its images) is located at ~/project/u-boot,
- BL33 should be ~/project/u-boot/u-boot.bin
-
- .. note::
-
- u-boot.bin should be used and not u-boot-spl.bin
-
- Set MSS/SCP image path (mandatory only for Armada80x0)::
-
- > export SCP_BL2=path/to/mrvl_scp_bl2*.img
-
-(3) Armada-37x0 build requires WTP tools installation.
-
- See below in the section "Tools and external components installation".
- Install ARM 32-bit cross compiler, which is required for building WTMI image for CM3::
-
- > sudo apt-get install gcc-arm-linux-gnueabi
-
-(4) Clean previous build residuals (if any)::
-
- > make distclean
-
-(5) Build TF-A:
-
- There are several build options:
-
- - DEBUG: default is without debug information (=0). in order to enable it use DEBUG=1
- Must be disabled when building UART recovery images due to current console driver
- implementation that is not compatible with Xmodem protocol used for boot image download.
-
- - LOG_LEVEL: defines the level of logging which will be purged to the default output port.
-
- LOG_LEVEL_NONE 0
- LOG_LEVEL_ERROR 10
- LOG_LEVEL_NOTICE 20
- LOG_LEVEL_WARNING 30
- LOG_LEVEL_INFO 40
- LOG_LEVEL_VERBOSE 50
-
- - USE_COHERENT_MEM: This flag determines whether to include the coherent memory region in the
- BL memory map or not.
-
- - LLC_ENABLE: Flag defining the LLC (L3) cache state. The cache is enabled by default (LLC_ENABLE=1).
-
- - MARVELL_SECURE_BOOT: build trusted(=1)/non trusted(=0) image, default is non trusted.
-
- - BLE_PATH:
- Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds.
- The parameter is optional, its default value is "plat/marvell/a8k/common/ble".
-
- - MV_DDR_PATH:
- For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0,
- it is used for ddr_tool build.
- Usage example: MV_DDR_PATH=path/to/mv_ddr
- The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr
- sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter
- is necessary for A37x0.
- For the mv_ddr source location, check the section "Tools and external components installation"
-
- - DDR_TOPOLOGY: For Armada37x0 only, the DDR topology map index/name, default is 0.
- Supported Options:
- - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB)
- - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB)
- - DDR3 2CS (2): EspressoBIN V3-V5 (1GB)
- - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB)
- - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB)
- - DDR4 1CS (5): EspressoBin V7 (1GB)
- - DDR4 2CS (6): EspressoBin V7 (2GB)
- - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB
-
- - CLOCKSPRESET: For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency,
- default is CPU_800_DDR_800.
- - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz
- - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz
- - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz
- - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz
-
- - BOOTDEV: For Armada37x0 only, the flash boot device, default is SPINOR,
- Currently, Armada37x0 only supports SPINOR, SPINAND, EMMCNORM and SATA:
-
- - SPINOR - SPI NOR flash boot
- - SPINAND - SPI NAND flash boot
- - EMMCNORM - eMMC Download Mode
- Download boot loader or program code from eMMC flash into CM3 or CA53
- Requires full initialization and command sequence
- - SATA - SATA device boot
-
- - PARTNUM: For Armada37x0 only, the boot partition number, default is 0. To boot from eMMC, the value
- should be aligned with the parameter in U-Boot with name of CONFIG_SYS_MMC_ENV_PART, whose
- value by default is 1.
- For details about CONFIG_SYS_MMC_ENV_PART, please refer to the U-Boot build instructions.
-
- - WTMI_IMG: For Armada37x0 only, the path of the WTMI image can point to an image which does
- nothing, an image which supports EFUSE or a customized CM3 firmware binary. The default image
- is wtmi.bin that built from sources in WTP folder, which is the next option. If the default
- image is OK, then this option should be skipped.
-
- - WTP: For Armada37x0 only, use this parameter to point to wtptools source code directory, which
- can be found as a3700_utils.zip in the release.
- Usage example: WTP=/path/to/a3700_utils
-
- For example, in order to build the image in debug mode with log level up to 'notice' level run::
-
- > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT=<MARVELL_PLATFORM> all fip
-
- And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level,
- the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR4 2CS,
- the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command
- line is as following::
-
- > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1000_DDR_800 \
- MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip
-
- Supported MARVELL_PLATFORM are:
- - a3700 (for both A3720 DB and EspressoBin)
- - a70x0
- - a70x0_amc (for AMC board)
- - a80x0
- - a80x0_mcbin (for MacciatoBin)
-
-Special Build Flags
---------------------
- - PLAT_RECOVERY_IMAGE_ENABLE: When set this option to enable secondary recovery function when build
- atf. In order to build UART recovery image this operation should be disabled for a70x0 and a80x0
- because of hardware limitation (boot from secondary image can interrupt UART recovery process).
- This MACRO definition is set in plat/marvell/a8k/common/include/platform_def.h file
-
-(for more information about build options, please refer to section 'Summary of build options' in TF-A user-guide:
- https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/user-guide.md)
-
-
-Build output
--------------
-Marvell's TF-A compilation generates 7 files:
- - ble.bin - BLe image
- - bl1.bin - BL1 image
- - bl2.bin - BL2 image
- - bl31.bin - BL31 image
- - fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images)
- - boot-image.bin - TF-A image (contains BL1 and FIP images)
- - flash-image.bin - Image which contains boot-image.bin and SPL image;
- should be placed on the boot flash/device.
-
-
-Tools and external components installation
-==========================================
-
-Armada37x0 Builds require installation of 3 components
--------------------------------------------------------
-
-(1) ARM cross compiler capable of building images for the service CPU (CM3).
- This component is usually included in the Linux host packages.
- On Debian/Ubuntu hosts the default GNU ARM tool chain can be installed
- using the following command::
-
- > sudo apt-get install gcc-arm-linux-gnueabi
-
- Only if required, the default tool chain prefix "arm-linux-gnueabi-" can be
- overwritten using the environment variable CROSS_CM3.
- Example for BASH shell::
-
- > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi
-
-(2) DDR initialization library sources (mv_ddr) available at the following repository
- (use the "mv_ddr-armada-atf-mainline" branch)::
- https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
-
-(3) Armada3700 tools available at the following repository (use the latest release branch)::
- https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git
-
-Armada70x0 and Armada80x0 Builds require installation of an additional component
---------------------------------------------------------------------------------
-
-(1) DDR initialization library sources (mv_ddr) available at the following repository
- (use the "mv_ddr-armada-atf-mainline" branch)::
- https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
-
+++ /dev/null
-Address decoding flow and address translation units of Marvell Armada 8K SoC family
-
-+--------------------------------------------------------------------------------------------------+
-| +-------------+ +--------------+ |
-| | Memory +----- DRAM CS | |
-|+------------+ +-----------+ +-----------+ | Controller | +--------------+ |
-|| AP DMA | | | | | +-------------+ |
-|| SD/eMMC | | CA72 CPUs | | AP MSS | +-------------+ |
-|| MCI-0/1 | | | | | | Memory | |
-|+------+-----+ +--+--------+ +--------+--+ +------------+ | Controller | +-------------+ |
-| | | | | +----- Translaton | |AP | |
-| | | | | | +-------------+ |Configuration| |
-| | | +-----+ +-------------------------Space | |
-| | | +-------------+ | CCU | +-------------+ |
-| | | | MMU +---------+ Windows | +-----------+ +-------------+ |
-| | +-| translation | | Lookup +---- +--------- AP SPI | |
-| | +-------------+ | | | | +-------------+ |
-| | +-------------+ | | | IO | +-------------+ |
-| +------------| SMMU +---------+ | | Windows +--------- AP MCI0/1 | |
-| | translation | +------------+ | Lookup | +-------------+ |
-| +---------+---+ | | +-------------+ |
-| - | | +--------- AP STM | |
-| +----------------- | | +-------------+ |
-| AP | | +-+---------+ |
-+---------------------------------------------------------------|----------------------------------+
-+-------------|-------------------------------------------------|----------------------------------+
-| CP | +-------------+ +------+-----+ +-------------------+ |
-| | | | | +------- SB CFG Space | |
-| | | DIOB | | | +-------------------+ |
-| | | Windows ----------------- IOB | +-------------------+ |
-| | | Control | | Windows +------| SB PCIe-0 - PCIe2 | |
-| | | | | Lookup | +-------------------+ |
-| | +------+------+ | | +-------------------+ |
-| | | | +------+ SB NAND | |
-| | | +------+-----+ +-------------------+ |
-| | | | |
-| | | | |
-| +------------------+ +------------+ +------+-----+ +-------------------+ |
-| | Network Engine | | | | +------- SB SPI-0/SPI-1 | |
-| | Security Engine | | PCIe, MSS | | RUNIT | +-------------------+ |
-| | SATA, USB | | DMA | | Windows | +-------------------+ |
-| | SD/eMMC | | | | Lookup +------- SB Device Bus | |
-| | TDM, I2C | | | | | +-------------------+ |
-| +------------------+ +------------+ +------------+ |
-| |
-+--------------------------------------------------------------------------------------------------+
-
+++ /dev/null
-AMB - AXI MBUS address decoding
--------------------------------
-
-AXI to M-bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs.
-
-- The Runit offers a second level of address windows lookup. It is used to map transaction towards
-the CD BootROM, SPI0, SPI1 and Device bus (NOR).
-- The Runit contains eight configurable windows. Each window defines a contiguous,
-address space and the properties associated with that address space.
-
-Unit Bank ATTR
-Device-Bus DEV_BOOT_CS 0x2F
- DEV_CS0 0x3E
- DEV_CS1 0x3D
- DEV_CS2 0x3B
- DEV_CS3 0x37
-SPI-0 SPI_A_CS0 0x1E
- SPI_A_CS1 0x5E
- SPI_A_CS2 0x9E
- SPI_A_CS3 0xDE
- SPI_A_CS4 0x1F
- SPI_A_CS5 0x5F
- SPI_A_CS6 0x9F
- SPI_A_CS7 0xDF
-SPI1 SPI_B_CS0 0x1A
- SPI_B_CS1 0x5A
- SPI_B_CS2 0x9A
- SPI_B_CS3 0xDA
-BOOT_ROM BOOT_ROM 0x1D
-UART UART 0x01
-
-Mandatory functions:
- - marvell_get_amb_memory_map
- returns the AMB windows configuration and the number of windows
-
-Mandatory structures:
- amb_memory_map - Array that include the configuration of the windows
- every window/entry is a struct which has 2 parameters:
- - base address of the window
- - Attribute of the window
-
-Examples:
- struct addr_map_win amb_memory_map[] = {
- {0xf900, AMB_DEV_CS0_ID},
- };
+++ /dev/null
-Marvell CCU address decoding bindings
-=====================================
-
-CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs.
-
-The CCU node includes a description of the address decoding configuration.
-
-Mandatory functions:
- - marvell_get_ccu_memory_map
- return the CCU windows configuration and the number of windows
- of the specific AP.
-
-Mandatory structures:
- ccu_memory_map - Array that includes the configuration of the windows
- every window/entry is a struct which has 3 parameters:
- - Base address of the window
- - Size of the window
- - Target-ID of the window
-
-Example:
- struct addr_map_win ccu_memory_map[] = {
- {0x00000000f2000000, 0x00000000e000000, IO_0_TID}, /* IO window */
- };
+++ /dev/null
-Marvell IO WIN address decoding bindings
-=====================================
-
-IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs.
-
-The IO WIN includes a description of the address decoding configuration.
-
-Transactions that are decoded by CCU windows as IO peripheral, have an additional
-layer of decoding. This additional address decoding layer defines one of the
-following targets:
- 0x0 = BootRom
- 0x1 = STM (Serial Trace Macro-cell, a programmer's port into trace stream)
- 0x2 = SPI direct access
- 0x3 = PCIe registers
- 0x4 = MCI Port
- 0x5 = PCIe port
-
-Mandatory functions:
- - marvell_get_io_win_memory_map
- returns the IO windows configuration and the number of windows
- of the specific AP.
-
-Mandatory structures:
- io_win_memory_map - Array that include the configuration of the windows
- every window/entry is a struct which has 3 parameters:
- - Base address of the window
- - Size of the window
- - Target-ID of the window
-
-Example:
- struct addr_map_win io_win_memory_map[] = {
- {0x00000000fe000000, 0x000000001f00000, PCIE_PORT_TID}, /* PCIe window 31Mb for PCIe port*/
- {0x00000000ffe00000, 0x000000000100000, PCIE_REGS_TID}, /* PCI-REG window 64Kb for PCIe-reg*/
- {0x00000000f6000000, 0x000000000100000, MCIPHY_TID}, /* MCI window 1Mb for PHY-reg*/
- };
+++ /dev/null
-Marvell IOB address decoding bindings
-=====================================
-
-IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs.
-
-The IOB includes a description of the address decoding configuration.
-
-IOB supports up to n (in CP110 n=24) windows for external memory transaction.
-When a transaction passes through the IOB, its address is compared to each of
-the enabled windows. If there is a hit and it passes the security checks, it is
-advanced to the target port.
-
-Mandatory functions:
- - marvell_get_iob_memory_map
- returns the IOB windows configuration and the number of windows
-
-Mandatory structures:
- iob_memory_map - Array that include the configuration of the windows
- every window/entry is a struct which has 3 parameters:
- - Base address of the window
- - Size of the window
- - Target-ID of the window
-
-Target ID options:
- - 0x0 = Internal configuration space
- - 0x1 = MCI0
- - 0x2 = PEX1_X1
- - 0x3 = PEX2_X1
- - 0x4 = PEX0_X4
- - 0x5 = NAND flash
- - 0x6 = RUNIT (NOR/SPI/BootRoom)
- - 0x7 = MCI1
-
-Example:
- struct addr_map_win iob_memory_map[] = {
- {0x00000000f7000000, 0x0000000001000000, PEX1_TID}, /* PEX1_X1 window */
- {0x00000000f8000000, 0x0000000001000000, PEX2_TID}, /* PEX2_X1 window */
- {0x00000000f6000000, 0x0000000001000000, PEX0_TID}, /* PEX0_X4 window */
- {0x00000000f9000000, 0x0000000001000000, NAND_TID} /* NAND window */
- };
+++ /dev/null
-.. _porting:
-
-TF-A Porting Guide
-=================
-
-This section describes how to port TF-A to a customer board, assuming that the SoC being used is already supported
-in TF-A.
-
-
-Source Code Structure
----------------------
-- The customer platform specific code shall reside under "plat/marvell/<soc family>/<soc>_cust"
- (e.g. 'plat/marvell/a8k/a7040_cust').
-- The platform name for build purposes is called "<soc>_cust" (e.g. a7040_cust).
-- The build system will reuse all files from within the soc directory, and take only the porting
- files from the customer platform directory.
-
-Files that require porting are located at "plat/marvell/<soc family>/<soc>_cust" directory.
-
-
-Armada-70x0/Armada-80x0 Porting
--------------------------------
-
- - SoC Physical Address Map (marvell_plat_config.c):
- - This file describes the SoC physical memory mapping to be used for the CCU, IOWIN, AXI-MBUS and IOB
- address decode units (Refer to the functional spec for more details).
- - In most cases, using the default address decode windows should work OK.
- - In cases where a special physical address map is needed (e.g. Special size for PCIe MEM windows,
- large memory mapped SPI flash...), then porting of the SoC memory map is required.
- - Note: For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please refer to the SoC functional spec,
- and under "docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt" files.
-
- - boot loader recovery (marvell_plat_config.c):
- - Background:
- boot rom can skip the current image and choose to boot from next position if a specific value
- (0xDEADB002) is returned by the ble main function. This feature is used for boot loader recovery
- by booting from a valid flash-image saved in next position on flash (e.g. address 2M in SPI flash).
-
- Supported options to implement the skip request are:
- - GPIO
- - I2C
- - User defined
-
- - Porting:
- Under marvell_plat_config.c, implement struct skip_image that includes specific board parameters.
- .. warning:: to disable this feature make sure the struct skip_image is not implemented.
-
- - Example:
- In A7040-DB specific implementation (plat/marvell/a8k/a70x0/board/marvell_plat_config.c),
- the image skip is implemented using GPIO: mpp 33 (SW5).
-
- Before resetting the board make sure there is a valid image on the next flash address:
- -tftp [valid address] flash-image.bin
- -sf update [valid address] 0x2000000 [size]
-
- Press reset and keep pressing the button connected to the chosen GPIO pin. A skip image request
- message is printed on the screen and boot rom boots from the saved image at the next position.
-
- - DDR Porting (dram_port.c):
- - This file defines the dram topology and parameters of the target board.
- - The DDR code is part of the BLE component, which is an extension of ARM Trusted Firmware (TF-A).
- - The DDR driver called mv_ddr is released separately apart from TF-A sources.
- - The BLE and consequently, the DDR init code is executed at the early stage of the boot process.
- - Each supported platform of the TF-A has its own DDR porting file called dram_port.c located at
- ``atf/plat/marvell/a8k/<platform>/board`` directory.
- - Please refer to '<path_to_mv_ddr_sources>/doc/porting_guide.txt' for detailed porting description.
- - The build target directory is "build/<platform>/release/ble".
-
- - Comphy Porting (phy-porting-layer.h or phy-default-porting-layer.h)
- - Background:
- Some of the comphy's parameters value depend on the HW connection between the SoC and the PHY. Every
- board type has specific HW characteristics like wire length. Due to those differences some comphy
- parameters vary between board types. Therefore each board type can have its own list of values for
- all relevant comphy parameters. The PHY porting layer specifies which parameters need to be suited and
- the board designer should provide relevant values.
-
- .. seealso::
- For XFI/SFI comphy type there is procedure "rx_training" which eases process of suiting some of
- the parameters. Please see :ref:`uboot_cmd` section: rx_training.
-
- The PHY porting layer simplifies updating static values per board type, which are now grouped in one place.
-
- .. note::
- The parameters for the same type of comphy may vary even for the same board type, it is because
- the lanes from comphy-x to some PHY may have different HW characteristic than lanes from
- comphy-y to the same (multiplexed) or other PHY.
-
- - Porting:
- The porting layer for PHY was introduced in TF-A. There is one file
- ``drivers/marvell/comphy/phy-default-porting-layer.h`` which contains the defaults. Those default
- parameters are used only if there is no appropriate phy-porting-layer.h file under:
- ``plat/marvell/<soc family>/<platform>/board/phy-porting-layer.h``. If the phy-porting-layer.h exists,
- the phy-default-porting-layer.h is not going to be included.
-
- .. warning::
- Not all comphy types are already reworked to support the PHY porting layer, currently the porting
- layer is supported for XFI/SFI and SATA comphy types.
-
- The easiest way to prepare the PHY porting layer for custom board is to copy existing example to a new
- platform:
-
- - cp ``plat/marvell/a8k/a80x0/board/phy-porting-layer.h`` "plat/marvell/<soc family>/<platform>/board/phy-porting-layer.h"
- - adjust relevant parameters or
- - if different comphy index is used for specific feature, move it to proper table entry and then adjust.
-
- .. note::
- The final table size with comphy parameters can be different, depending on the CP module count for
- given SoC type.
-
- - Example:
- Example porting layer for armada-8040-db is under: ``plat/marvell/a8k/a80x0/board/phy-porting-layer.h``
-
- .. note::
- If there is no PHY porting layer for new platform (missing phy-porting-layer.h), the default
- values are used (drivers/marvell/comphy/phy-default-porting-layer.h) and the user is warned:
-
- .. warning::
- "Using default comphy parameters - it may be required to suit them for your board".
--- /dev/null
+Performance & Testing
+=====================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+ :numbered:
+
+ psci-performance-juno
--- /dev/null
+PSCI Performance Measurements on Arm Juno Development Platform
+==============================================================
+
+This document summarises the findings of performance measurements of key
+operations in the ARM Trusted Firmware (TF) Power State Coordination Interface
+(PSCI) implementation, using the in-built Performance Measurement Framework
+(PMF) and runtime instrumentation timestamps.
+
+Method
+------
+
+We used the `Juno R1 platform`_ for these tests, which has 4 x Cortex-A53 and 2
+x Cortex-A57 clusters running at the following frequencies:
+
++-----------------+--------------------+
+| Domain | Frequency (MHz) |
++=================+====================+
+| Cortex-A57 | 900 (nominal) |
++-----------------+--------------------+
+| Cortex-A53 | 650 (underdrive) |
++-----------------+--------------------+
+| AXI subsystem | 533 |
++-----------------+--------------------+
+
+Juno supports CPU, cluster and system power down states, corresponding to power
+levels 0, 1 and 2 respectively. It does not support any retention states.
+
+We used the upstream `TF master as of 31/01/2017`_, building the platform using
+the ``ENABLE_RUNTIME_INSTRUMENTATION`` option:
+
+::
+
+ make PLAT=juno ENABLE_RUNTIME_INSTRUMENTATION=1 \
+ SCP_BL2=<path/to/scp-fw.bin> \
+ BL33=<path/to/test-fw.bin> \
+ all fip
+
+When using the debug build of TF, there was no noticeable difference in the
+results.
+
+The tests are based on an ARM-internal test framework. The release build of this
+framework was used because the results in the debug build became skewed; the
+console output prevented some of the tests from executing in parallel.
+
+The tests consist of both parallel and sequential tests, which are broadly
+described as follows:
+
+- **Parallel Tests** This type of test powers on all the non-lead CPUs and
+ brings them and the lead CPU to a common synchronization point. The lead CPU
+ then initiates the test on all CPUs in parallel.
+
+- **Sequential Tests** This type of test powers on each non-lead CPU in
+ sequence. The lead CPU initiates the test on a non-lead CPU then waits for the
+ test to complete before proceeding to the next non-lead CPU. The lead CPU then
+ executes the test on itself.
+
+In the results below, CPUs 0-3 refer to CPUs in the little cluster (A53) and
+CPUs 4-5 refer to CPUs in the big cluster (A57). In all cases CPU 4 is the lead
+CPU.
+
+``PSCI_ENTRY`` refers to the time taken from entering the TF PSCI implementation
+to the point the hardware enters the low power state (WFI). Referring to the TF
+runtime instrumentation points, this corresponds to:
+``(RT_INSTR_ENTER_HW_LOW_PWR - RT_INSTR_ENTER_PSCI)``.
+
+``PSCI_EXIT`` refers to the time taken from the point the hardware exits the low
+power state to exiting the TF PSCI implementation. This corresponds to:
+``(RT_INSTR_EXIT_PSCI - RT_INSTR_EXIT_HW_LOW_PWR)``.
+
+``CFLUSH_OVERHEAD`` refers to the part of ``PSCI_ENTRY`` taken to flush the
+caches. This corresponds to: ``(RT_INSTR_EXIT_CFLUSH - RT_INSTR_ENTER_CFLUSH)``.
+
+Note there is very little variance observed in the values given (~1us), although
+the values for each CPU are sometimes interchanged, depending on the order in
+which locks are acquired. Also, there is very little variance observed between
+executing the tests sequentially in a single boot or rebooting between tests.
+
+Given that runtime instrumentation using PMF is invasive, there is a small
+(unquantified) overhead on the results. PMF uses the generic counter for
+timestamps, which runs at 50MHz on Juno.
+
+Results and Commentary
+----------------------
+
+``CPU_SUSPEND`` to deepest power level on all CPUs in parallel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++-------+---------------------+--------------------+--------------------------+
+| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
++=======+=====================+====================+==========================+
+| 0 | 27 | 20 | 5 |
++-------+---------------------+--------------------+--------------------------+
+| 1 | 114 | 86 | 5 |
++-------+---------------------+--------------------+--------------------------+
+| 2 | 202 | 58 | 5 |
++-------+---------------------+--------------------+--------------------------+
+| 3 | 375 | 29 | 94 |
++-------+---------------------+--------------------+--------------------------+
+| 4 | 20 | 22 | 6 |
++-------+---------------------+--------------------+--------------------------+
+| 5 | 290 | 18 | 206 |
++-------+---------------------+--------------------+--------------------------+
+
+A large variance in ``PSCI_ENTRY`` and ``PSCI_EXIT`` times across CPUs is
+observed due to TF PSCI lock contention. In the worst case, CPU 3 has to wait
+for the 3 other CPUs in the cluster (0-2) to complete ``PSCI_ENTRY`` and release
+the lock before proceeding.
+
+The ``CFLUSH_OVERHEAD`` times for CPUs 3 and 5 are higher because they are the
+last CPUs in their respective clusters to power down, therefore both the L1 and
+L2 caches are flushed.
+
+The ``CFLUSH_OVERHEAD`` time for CPU 5 is a lot larger than that for CPU 3
+because the L2 cache size for the big cluster is lot larger (2MB) compared to
+the little cluster (1MB).
+
+``CPU_SUSPEND`` to power level 0 on all CPUs in parallel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++-------+---------------------+--------------------+--------------------------+
+| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
++=======+=====================+====================+==========================+
+| 0 | 116 | 14 | 8 |
++-------+---------------------+--------------------+--------------------------+
+| 1 | 204 | 14 | 8 |
++-------+---------------------+--------------------+--------------------------+
+| 2 | 287 | 13 | 8 |
++-------+---------------------+--------------------+--------------------------+
+| 3 | 376 | 13 | 9 |
++-------+---------------------+--------------------+--------------------------+
+| 4 | 29 | 15 | 7 |
++-------+---------------------+--------------------+--------------------------+
+| 5 | 21 | 15 | 8 |
++-------+---------------------+--------------------+--------------------------+
+
+There is no lock contention in TF generic code at power level 0 but the large
+variance in ``PSCI_ENTRY`` times across CPUs is due to lock contention in Juno
+platform code. The platform lock is used to mediate access to a single SCP
+communication channel. This is compounded by the SCP firmware waiting for each
+AP CPU to enter WFI before making the channel available to other CPUs, which
+effectively serializes the SCP power down commands from all CPUs.
+
+On platforms with a more efficient CPU power down mechanism, it should be
+possible to make the ``PSCI_ENTRY`` times smaller and consistent.
+
+The ``PSCI_EXIT`` times are consistent across all CPUs because TF does not
+require locks at power level 0.
+
+The ``CFLUSH_OVERHEAD`` times for all CPUs are small and consistent since only
+the cache associated with power level 0 is flushed (L1).
+
+``CPU_SUSPEND`` to deepest power level on all CPUs in sequence
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++-------+---------------------+--------------------+--------------------------+
+| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
++=======+=====================+====================+==========================+
+| 0 | 114 | 20 | 94 |
++-------+---------------------+--------------------+--------------------------+
+| 1 | 114 | 20 | 94 |
++-------+---------------------+--------------------+--------------------------+
+| 2 | 114 | 20 | 94 |
++-------+---------------------+--------------------+--------------------------+
+| 3 | 114 | 20 | 94 |
++-------+---------------------+--------------------+--------------------------+
+| 4 | 195 | 22 | 180 |
++-------+---------------------+--------------------+--------------------------+
+| 5 | 21 | 17 | 6 |
++-------+---------------------+--------------------+--------------------------+
+
+The ``CLUSH_OVERHEAD`` times for lead CPU 4 and all CPUs in the non-lead cluster
+are large because all other CPUs in the cluster are powered down during the
+test. The ``CPU_SUSPEND`` call powers down to the cluster level, requiring a
+flush of both L1 and L2 caches.
+
+The ``CFLUSH_OVERHEAD`` time for CPU 4 is a lot larger than those for the little
+CPUs because the L2 cache size for the big cluster is lot larger (2MB) compared
+to the little cluster (1MB).
+
+The ``PSCI_ENTRY`` and ``CFLUSH_OVERHEAD`` times for CPU 5 are low because lead
+CPU 4 continues to run while CPU 5 is suspended. Hence CPU 5 only powers down to
+level 0, which only requires L1 cache flush.
+
+``CPU_SUSPEND`` to power level 0 on all CPUs in sequence
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
++-------+---------------------+--------------------+--------------------------+
+| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
++=======+=====================+====================+==========================+
+| 0 | 22 | 14 | 5 |
++-------+---------------------+--------------------+--------------------------+
+| 1 | 22 | 14 | 5 |
++-------+---------------------+--------------------+--------------------------+
+| 2 | 21 | 14 | 5 |
++-------+---------------------+--------------------+--------------------------+
+| 3 | 22 | 14 | 5 |
++-------+---------------------+--------------------+--------------------------+
+| 4 | 17 | 14 | 6 |
++-------+---------------------+--------------------+--------------------------+
+| 5 | 18 | 15 | 6 |
++-------+---------------------+--------------------+--------------------------+
+
+Here the times are small and consistent since there is no contention and it is
+only necessary to flush the cache to power level 0 (L1). This is the best case
+scenario.
+
+The ``PSCI_ENTRY`` times for CPUs in the big cluster are slightly smaller than
+for the CPUs in little cluster due to greater CPU performance.
+
+The ``PSCI_EXIT`` times are generally lower than in the last test because the
+cluster remains powered on throughout the test and there is less code to execute
+on power on (for example, no need to enter CCI coherency)
+
+``CPU_OFF`` on all non-lead CPUs in sequence then ``CPU_SUSPEND`` on lead CPU to deepest power level
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The test sequence here is as follows:
+
+1. Call ``CPU_ON`` and ``CPU_OFF`` on each non-lead CPU in sequence.
+
+2. Program wake up timer and suspend the lead CPU to the deepest power level.
+
+3. Call ``CPU_ON`` on non-lead CPU to get the timestamps from each CPU.
+
++-------+---------------------+--------------------+--------------------------+
+| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
++=======+=====================+====================+==========================+
+| 0 | 110 | 28 | 93 |
++-------+---------------------+--------------------+--------------------------+
+| 1 | 110 | 28 | 93 |
++-------+---------------------+--------------------+--------------------------+
+| 2 | 110 | 28 | 93 |
++-------+---------------------+--------------------+--------------------------+
+| 3 | 111 | 28 | 93 |
++-------+---------------------+--------------------+--------------------------+
+| 4 | 195 | 22 | 181 |
++-------+---------------------+--------------------+--------------------------+
+| 5 | 20 | 23 | 6 |
++-------+---------------------+--------------------+--------------------------+
+
+The ``CFLUSH_OVERHEAD`` times for all little CPUs are large because all other
+CPUs in that cluster are powerered down during the test. The ``CPU_OFF`` call
+powers down to the cluster level, requiring a flush of both L1 and L2 caches.
+
+The ``PSCI_ENTRY`` and ``CFLUSH_OVERHEAD`` times for CPU 5 are small because
+lead CPU 4 is running and CPU 5 only powers down to level 0, which only requires
+an L1 cache flush.
+
+The ``CFLUSH_OVERHEAD`` time for CPU 4 is a lot larger than those for the little
+CPUs because the L2 cache size for the big cluster is lot larger (2MB) compared
+to the little cluster (1MB).
+
+The ``PSCI_EXIT`` times for CPUs in the big cluster are slightly smaller than
+for CPUs in the little cluster due to greater CPU performance. These times
+generally are greater than the ``PSCI_EXIT`` times in the ``CPU_SUSPEND`` tests
+because there is more code to execute in the "on finisher" compared to the
+"suspend finisher" (for example, GIC redistributor register programming).
+
+``PSCI_VERSION`` on all CPUs in parallel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since very little code is associated with ``PSCI_VERSION``, this test
+approximates the round trip latency for handling a fast SMC at EL3 in TF.
+
++-------+-------------------+
+| CPU | TOTAL TIME (ns) |
++=======+===================+
+| 0 | 3020 |
++-------+-------------------+
+| 1 | 2940 |
++-------+-------------------+
+| 2 | 2980 |
++-------+-------------------+
+| 3 | 3060 |
++-------+-------------------+
+| 4 | 520 |
++-------+-------------------+
+| 5 | 720 |
++-------+-------------------+
+
+The times for the big CPUs are less than the little CPUs due to greater CPU
+performance.
+
+We suspect the time for lead CPU 4 is shorter than CPU 5 due to subtle cache
+effects, given that these measurements are at the nano-second level.
+
+.. _Juno R1 platform: https://www.arm.com/files/pdf/Juno_r1_ARM_Dev_datasheet.pdf
+.. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
--- /dev/null
+Platform Ports
+==============
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+ :numbered:
+
+ allwinner
+ fvp_ve
+ imx8
+ imx8m
+ intel-stratix10
+ ls1043a
+ meson-gxbb
+ meson-gxl
+ mt8183
+ nvidia-tegra
+ poplar
+ qemu
+ rcar-gen3
+ rockchip
+ rpi3
+ socionext-uniphier
+ stm32mp1
+ synquacer
+ ti-k3
+ warp7
+ xilinx-zynqmp
--- /dev/null
+TF-A Build Instructions
+======================
+
+This section describes how to compile the ARM Trusted Firmware (TF-A) project for Marvell's platforms.
+
+Build Instructions
+------------------
+(1) Set the cross compiler::
+
+ > export CROSS_COMPILE=/path/to/toolchain/aarch64-linux-gnu-
+
+(2) Set path for FIP images:
+
+ Set U-Boot image path (relatively to TF-A root or absolute path)::
+
+ > export BL33=path/to/u-boot.bin
+
+ For example: if U-Boot project (and its images) is located at ~/project/u-boot,
+ BL33 should be ~/project/u-boot/u-boot.bin
+
+ .. note::
+
+ u-boot.bin should be used and not u-boot-spl.bin
+
+ Set MSS/SCP image path (mandatory only for Armada80x0)::
+
+ > export SCP_BL2=path/to/mrvl_scp_bl2*.img
+
+(3) Armada-37x0 build requires WTP tools installation.
+
+ See below in the section "Tools and external components installation".
+ Install ARM 32-bit cross compiler, which is required for building WTMI image for CM3::
+
+ > sudo apt-get install gcc-arm-linux-gnueabi
+
+(4) Clean previous build residuals (if any)::
+
+ > make distclean
+
+(5) Build TF-A:
+
+ There are several build options:
+
+ - DEBUG: default is without debug information (=0). in order to enable it use DEBUG=1
+ Must be disabled when building UART recovery images due to current console driver
+ implementation that is not compatible with Xmodem protocol used for boot image download.
+
+ - LOG_LEVEL: defines the level of logging which will be purged to the default output port.
+
+ LOG_LEVEL_NONE 0
+ LOG_LEVEL_ERROR 10
+ LOG_LEVEL_NOTICE 20
+ LOG_LEVEL_WARNING 30
+ LOG_LEVEL_INFO 40
+ LOG_LEVEL_VERBOSE 50
+
+ - USE_COHERENT_MEM: This flag determines whether to include the coherent memory region in the
+ BL memory map or not.
+
+ - LLC_ENABLE: Flag defining the LLC (L3) cache state. The cache is enabled by default (LLC_ENABLE=1).
+
+ - MARVELL_SECURE_BOOT: build trusted(=1)/non trusted(=0) image, default is non trusted.
+
+ - BLE_PATH:
+ Points to BLE (Binary ROM extension) sources folder. Only required for A8K builds.
+ The parameter is optional, its default value is "plat/marvell/a8k/common/ble".
+
+ - MV_DDR_PATH:
+ For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0,
+ it is used for ddr_tool build.
+ Usage example: MV_DDR_PATH=path/to/mv_ddr
+ The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr
+ sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter
+ is necessary for A37x0.
+ For the mv_ddr source location, check the section "Tools and external components installation"
+
+ - DDR_TOPOLOGY: For Armada37x0 only, the DDR topology map index/name, default is 0.
+ Supported Options:
+ - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB)
+ - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB)
+ - DDR3 2CS (2): EspressoBIN V3-V5 (1GB)
+ - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB)
+ - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB)
+ - DDR4 1CS (5): EspressoBin V7 (1GB)
+ - DDR4 2CS (6): EspressoBin V7 (2GB)
+ - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB
+
+ - CLOCKSPRESET: For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency,
+ default is CPU_800_DDR_800.
+ - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz
+ - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz
+ - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz
+ - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz
+
+ - BOOTDEV: For Armada37x0 only, the flash boot device, default is SPINOR,
+ Currently, Armada37x0 only supports SPINOR, SPINAND, EMMCNORM and SATA:
+
+ - SPINOR - SPI NOR flash boot
+ - SPINAND - SPI NAND flash boot
+ - EMMCNORM - eMMC Download Mode
+ Download boot loader or program code from eMMC flash into CM3 or CA53
+ Requires full initialization and command sequence
+ - SATA - SATA device boot
+
+ - PARTNUM: For Armada37x0 only, the boot partition number, default is 0. To boot from eMMC, the value
+ should be aligned with the parameter in U-Boot with name of CONFIG_SYS_MMC_ENV_PART, whose
+ value by default is 1.
+ For details about CONFIG_SYS_MMC_ENV_PART, please refer to the U-Boot build instructions.
+
+ - WTMI_IMG: For Armada37x0 only, the path of the WTMI image can point to an image which does
+ nothing, an image which supports EFUSE or a customized CM3 firmware binary. The default image
+ is wtmi.bin that built from sources in WTP folder, which is the next option. If the default
+ image is OK, then this option should be skipped.
+
+ - WTP: For Armada37x0 only, use this parameter to point to wtptools source code directory, which
+ can be found as a3700_utils.zip in the release.
+ Usage example: WTP=/path/to/a3700_utils
+
+ For example, in order to build the image in debug mode with log level up to 'notice' level run::
+
+ > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT=<MARVELL_PLATFORM> all fip
+
+ And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level,
+ the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR4 2CS,
+ the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command
+ line is as following::
+
+ > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 CLOCKSPRESET=CPU_1000_DDR_800 \
+ MARVELL_SECURE_BOOT=0 DDR_TOPOLOGY=3 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip
+
+ Supported MARVELL_PLATFORM are:
+ - a3700 (for both A3720 DB and EspressoBin)
+ - a70x0
+ - a70x0_amc (for AMC board)
+ - a80x0
+ - a80x0_mcbin (for MacciatoBin)
+
+Special Build Flags
+--------------------
+ - PLAT_RECOVERY_IMAGE_ENABLE: When set this option to enable secondary recovery function when build
+ atf. In order to build UART recovery image this operation should be disabled for a70x0 and a80x0
+ because of hardware limitation (boot from secondary image can interrupt UART recovery process).
+ This MACRO definition is set in plat/marvell/a8k/common/include/platform_def.h file
+
+(for more information about build options, please refer to section 'Summary of build options' in TF-A user-guide:
+ https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/user-guide.md)
+
+
+Build output
+-------------
+Marvell's TF-A compilation generates 7 files:
+ - ble.bin - BLe image
+ - bl1.bin - BL1 image
+ - bl2.bin - BL2 image
+ - bl31.bin - BL31 image
+ - fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images)
+ - boot-image.bin - TF-A image (contains BL1 and FIP images)
+ - flash-image.bin - Image which contains boot-image.bin and SPL image;
+ should be placed on the boot flash/device.
+
+
+Tools and external components installation
+==========================================
+
+Armada37x0 Builds require installation of 3 components
+-------------------------------------------------------
+
+(1) ARM cross compiler capable of building images for the service CPU (CM3).
+ This component is usually included in the Linux host packages.
+ On Debian/Ubuntu hosts the default GNU ARM tool chain can be installed
+ using the following command::
+
+ > sudo apt-get install gcc-arm-linux-gnueabi
+
+ Only if required, the default tool chain prefix "arm-linux-gnueabi-" can be
+ overwritten using the environment variable CROSS_CM3.
+ Example for BASH shell::
+
+ > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi
+
+(2) DDR initialization library sources (mv_ddr) available at the following repository
+ (use the "mv_ddr-armada-atf-mainline" branch)::
+ https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
+
+(3) Armada3700 tools available at the following repository (use the latest release branch)::
+ https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell.git
+
+Armada70x0 and Armada80x0 Builds require installation of an additional component
+--------------------------------------------------------------------------------
+
+(1) DDR initialization library sources (mv_ddr) available at the following repository
+ (use the "mv_ddr-armada-atf-mainline" branch)::
+ https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git
+
--- /dev/null
+Address decoding flow and address translation units of Marvell Armada 8K SoC family
+
++--------------------------------------------------------------------------------------------------+
+| +-------------+ +--------------+ |
+| | Memory +----- DRAM CS | |
+|+------------+ +-----------+ +-----------+ | Controller | +--------------+ |
+|| AP DMA | | | | | +-------------+ |
+|| SD/eMMC | | CA72 CPUs | | AP MSS | +-------------+ |
+|| MCI-0/1 | | | | | | Memory | |
+|+------+-----+ +--+--------+ +--------+--+ +------------+ | Controller | +-------------+ |
+| | | | | +----- Translaton | |AP | |
+| | | | | | +-------------+ |Configuration| |
+| | | +-----+ +-------------------------Space | |
+| | | +-------------+ | CCU | +-------------+ |
+| | | | MMU +---------+ Windows | +-----------+ +-------------+ |
+| | +-| translation | | Lookup +---- +--------- AP SPI | |
+| | +-------------+ | | | | +-------------+ |
+| | +-------------+ | | | IO | +-------------+ |
+| +------------| SMMU +---------+ | | Windows +--------- AP MCI0/1 | |
+| | translation | +------------+ | Lookup | +-------------+ |
+| +---------+---+ | | +-------------+ |
+| - | | +--------- AP STM | |
+| +----------------- | | +-------------+ |
+| AP | | +-+---------+ |
++---------------------------------------------------------------|----------------------------------+
++-------------|-------------------------------------------------|----------------------------------+
+| CP | +-------------+ +------+-----+ +-------------------+ |
+| | | | | +------- SB CFG Space | |
+| | | DIOB | | | +-------------------+ |
+| | | Windows ----------------- IOB | +-------------------+ |
+| | | Control | | Windows +------| SB PCIe-0 - PCIe2 | |
+| | | | | Lookup | +-------------------+ |
+| | +------+------+ | | +-------------------+ |
+| | | | +------+ SB NAND | |
+| | | +------+-----+ +-------------------+ |
+| | | | |
+| | | | |
+| +------------------+ +------------+ +------+-----+ +-------------------+ |
+| | Network Engine | | | | +------- SB SPI-0/SPI-1 | |
+| | Security Engine | | PCIe, MSS | | RUNIT | +-------------------+ |
+| | SATA, USB | | DMA | | Windows | +-------------------+ |
+| | SD/eMMC | | | | Lookup +------- SB Device Bus | |
+| | TDM, I2C | | | | | +-------------------+ |
+| +------------------+ +------------+ +------------+ |
+| |
++--------------------------------------------------------------------------------------------------+
+
--- /dev/null
+AMB - AXI MBUS address decoding
+-------------------------------
+
+AXI to M-bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs.
+
+- The Runit offers a second level of address windows lookup. It is used to map transaction towards
+the CD BootROM, SPI0, SPI1 and Device bus (NOR).
+- The Runit contains eight configurable windows. Each window defines a contiguous,
+address space and the properties associated with that address space.
+
+Unit Bank ATTR
+Device-Bus DEV_BOOT_CS 0x2F
+ DEV_CS0 0x3E
+ DEV_CS1 0x3D
+ DEV_CS2 0x3B
+ DEV_CS3 0x37
+SPI-0 SPI_A_CS0 0x1E
+ SPI_A_CS1 0x5E
+ SPI_A_CS2 0x9E
+ SPI_A_CS3 0xDE
+ SPI_A_CS4 0x1F
+ SPI_A_CS5 0x5F
+ SPI_A_CS6 0x9F
+ SPI_A_CS7 0xDF
+SPI1 SPI_B_CS0 0x1A
+ SPI_B_CS1 0x5A
+ SPI_B_CS2 0x9A
+ SPI_B_CS3 0xDA
+BOOT_ROM BOOT_ROM 0x1D
+UART UART 0x01
+
+Mandatory functions:
+ - marvell_get_amb_memory_map
+ returns the AMB windows configuration and the number of windows
+
+Mandatory structures:
+ amb_memory_map - Array that include the configuration of the windows
+ every window/entry is a struct which has 2 parameters:
+ - base address of the window
+ - Attribute of the window
+
+Examples:
+ struct addr_map_win amb_memory_map[] = {
+ {0xf900, AMB_DEV_CS0_ID},
+ };
--- /dev/null
+Marvell CCU address decoding bindings
+=====================================
+
+CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs.
+
+The CCU node includes a description of the address decoding configuration.
+
+Mandatory functions:
+ - marvell_get_ccu_memory_map
+ return the CCU windows configuration and the number of windows
+ of the specific AP.
+
+Mandatory structures:
+ ccu_memory_map - Array that includes the configuration of the windows
+ every window/entry is a struct which has 3 parameters:
+ - Base address of the window
+ - Size of the window
+ - Target-ID of the window
+
+Example:
+ struct addr_map_win ccu_memory_map[] = {
+ {0x00000000f2000000, 0x00000000e000000, IO_0_TID}, /* IO window */
+ };
--- /dev/null
+Marvell IO WIN address decoding bindings
+=====================================
+
+IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs.
+
+The IO WIN includes a description of the address decoding configuration.
+
+Transactions that are decoded by CCU windows as IO peripheral, have an additional
+layer of decoding. This additional address decoding layer defines one of the
+following targets:
+ 0x0 = BootRom
+ 0x1 = STM (Serial Trace Macro-cell, a programmer's port into trace stream)
+ 0x2 = SPI direct access
+ 0x3 = PCIe registers
+ 0x4 = MCI Port
+ 0x5 = PCIe port
+
+Mandatory functions:
+ - marvell_get_io_win_memory_map
+ returns the IO windows configuration and the number of windows
+ of the specific AP.
+
+Mandatory structures:
+ io_win_memory_map - Array that include the configuration of the windows
+ every window/entry is a struct which has 3 parameters:
+ - Base address of the window
+ - Size of the window
+ - Target-ID of the window
+
+Example:
+ struct addr_map_win io_win_memory_map[] = {
+ {0x00000000fe000000, 0x000000001f00000, PCIE_PORT_TID}, /* PCIe window 31Mb for PCIe port*/
+ {0x00000000ffe00000, 0x000000000100000, PCIE_REGS_TID}, /* PCI-REG window 64Kb for PCIe-reg*/
+ {0x00000000f6000000, 0x000000000100000, MCIPHY_TID}, /* MCI window 1Mb for PHY-reg*/
+ };
--- /dev/null
+Marvell IOB address decoding bindings
+=====================================
+
+IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs.
+
+The IOB includes a description of the address decoding configuration.
+
+IOB supports up to n (in CP110 n=24) windows for external memory transaction.
+When a transaction passes through the IOB, its address is compared to each of
+the enabled windows. If there is a hit and it passes the security checks, it is
+advanced to the target port.
+
+Mandatory functions:
+ - marvell_get_iob_memory_map
+ returns the IOB windows configuration and the number of windows
+
+Mandatory structures:
+ iob_memory_map - Array that include the configuration of the windows
+ every window/entry is a struct which has 3 parameters:
+ - Base address of the window
+ - Size of the window
+ - Target-ID of the window
+
+Target ID options:
+ - 0x0 = Internal configuration space
+ - 0x1 = MCI0
+ - 0x2 = PEX1_X1
+ - 0x3 = PEX2_X1
+ - 0x4 = PEX0_X4
+ - 0x5 = NAND flash
+ - 0x6 = RUNIT (NOR/SPI/BootRoom)
+ - 0x7 = MCI1
+
+Example:
+ struct addr_map_win iob_memory_map[] = {
+ {0x00000000f7000000, 0x0000000001000000, PEX1_TID}, /* PEX1_X1 window */
+ {0x00000000f8000000, 0x0000000001000000, PEX2_TID}, /* PEX2_X1 window */
+ {0x00000000f6000000, 0x0000000001000000, PEX0_TID}, /* PEX0_X4 window */
+ {0x00000000f9000000, 0x0000000001000000, NAND_TID} /* NAND window */
+ };
--- /dev/null
+.. _porting:
+
+TF-A Porting Guide
+=================
+
+This section describes how to port TF-A to a customer board, assuming that the SoC being used is already supported
+in TF-A.
+
+
+Source Code Structure
+---------------------
+- The customer platform specific code shall reside under "plat/marvell/<soc family>/<soc>_cust"
+ (e.g. 'plat/marvell/a8k/a7040_cust').
+- The platform name for build purposes is called "<soc>_cust" (e.g. a7040_cust).
+- The build system will reuse all files from within the soc directory, and take only the porting
+ files from the customer platform directory.
+
+Files that require porting are located at "plat/marvell/<soc family>/<soc>_cust" directory.
+
+
+Armada-70x0/Armada-80x0 Porting
+-------------------------------
+
+ - SoC Physical Address Map (marvell_plat_config.c):
+ - This file describes the SoC physical memory mapping to be used for the CCU, IOWIN, AXI-MBUS and IOB
+ address decode units (Refer to the functional spec for more details).
+ - In most cases, using the default address decode windows should work OK.
+ - In cases where a special physical address map is needed (e.g. Special size for PCIe MEM windows,
+ large memory mapped SPI flash...), then porting of the SoC memory map is required.
+ - Note: For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please refer to the SoC functional spec,
+ and under "docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt" files.
+
+ - boot loader recovery (marvell_plat_config.c):
+ - Background:
+ boot rom can skip the current image and choose to boot from next position if a specific value
+ (0xDEADB002) is returned by the ble main function. This feature is used for boot loader recovery
+ by booting from a valid flash-image saved in next position on flash (e.g. address 2M in SPI flash).
+
+ Supported options to implement the skip request are:
+ - GPIO
+ - I2C
+ - User defined
+
+ - Porting:
+ Under marvell_plat_config.c, implement struct skip_image that includes specific board parameters.
+ .. warning:: to disable this feature make sure the struct skip_image is not implemented.
+
+ - Example:
+ In A7040-DB specific implementation (plat/marvell/a8k/a70x0/board/marvell_plat_config.c),
+ the image skip is implemented using GPIO: mpp 33 (SW5).
+
+ Before resetting the board make sure there is a valid image on the next flash address:
+ -tftp [valid address] flash-image.bin
+ -sf update [valid address] 0x2000000 [size]
+
+ Press reset and keep pressing the button connected to the chosen GPIO pin. A skip image request
+ message is printed on the screen and boot rom boots from the saved image at the next position.
+
+ - DDR Porting (dram_port.c):
+ - This file defines the dram topology and parameters of the target board.
+ - The DDR code is part of the BLE component, which is an extension of ARM Trusted Firmware (TF-A).
+ - The DDR driver called mv_ddr is released separately apart from TF-A sources.
+ - The BLE and consequently, the DDR init code is executed at the early stage of the boot process.
+ - Each supported platform of the TF-A has its own DDR porting file called dram_port.c located at
+ ``atf/plat/marvell/a8k/<platform>/board`` directory.
+ - Please refer to '<path_to_mv_ddr_sources>/doc/porting_guide.txt' for detailed porting description.
+ - The build target directory is "build/<platform>/release/ble".
+
+ - Comphy Porting (phy-porting-layer.h or phy-default-porting-layer.h)
+ - Background:
+ Some of the comphy's parameters value depend on the HW connection between the SoC and the PHY. Every
+ board type has specific HW characteristics like wire length. Due to those differences some comphy
+ parameters vary between board types. Therefore each board type can have its own list of values for
+ all relevant comphy parameters. The PHY porting layer specifies which parameters need to be suited and
+ the board designer should provide relevant values.
+
+ .. seealso::
+ For XFI/SFI comphy type there is procedure "rx_training" which eases process of suiting some of
+ the parameters. Please see :ref:`uboot_cmd` section: rx_training.
+
+ The PHY porting layer simplifies updating static values per board type, which are now grouped in one place.
+
+ .. note::
+ The parameters for the same type of comphy may vary even for the same board type, it is because
+ the lanes from comphy-x to some PHY may have different HW characteristic than lanes from
+ comphy-y to the same (multiplexed) or other PHY.
+
+ - Porting:
+ The porting layer for PHY was introduced in TF-A. There is one file
+ ``drivers/marvell/comphy/phy-default-porting-layer.h`` which contains the defaults. Those default
+ parameters are used only if there is no appropriate phy-porting-layer.h file under:
+ ``plat/marvell/<soc family>/<platform>/board/phy-porting-layer.h``. If the phy-porting-layer.h exists,
+ the phy-default-porting-layer.h is not going to be included.
+
+ .. warning::
+ Not all comphy types are already reworked to support the PHY porting layer, currently the porting
+ layer is supported for XFI/SFI and SATA comphy types.
+
+ The easiest way to prepare the PHY porting layer for custom board is to copy existing example to a new
+ platform:
+
+ - cp ``plat/marvell/a8k/a80x0/board/phy-porting-layer.h`` "plat/marvell/<soc family>/<platform>/board/phy-porting-layer.h"
+ - adjust relevant parameters or
+ - if different comphy index is used for specific feature, move it to proper table entry and then adjust.
+
+ .. note::
+ The final table size with comphy parameters can be different, depending on the CP module count for
+ given SoC type.
+
+ - Example:
+ Example porting layer for armada-8040-db is under: ``plat/marvell/a8k/a80x0/board/phy-porting-layer.h``
+
+ .. note::
+ If there is no PHY porting layer for new platform (missing phy-porting-layer.h), the default
+ values are used (drivers/marvell/comphy/phy-default-porting-layer.h) and the user is warned:
+
+ .. warning::
+ "Using default comphy parameters - it may be required to suit them for your board".
Trusted Firmware-A for Raspberry Pi 3
=====================================
-.. section-numbering::
- :suffix: .
+
.. contents::
+++ /dev/null
-TF-A Platform Compatibility Policy
-==================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
---------------
-
-Introduction
-------------
-
-This document clarifies the project's policy around compatibility for upstream
-platforms.
-
-Platform compatibility policy
------------------------------
-
-Platform compatibility is mainly affected by changes to Platform APIs (as
-documented in the `Porting Guide`_), driver APIs (like the GICv3 drivers) or
-library interfaces (like xlat_table library). The project will try to maintain
-compatibility for upstream platforms. Due to evolving requirements and
-enhancements, there might be changes affecting platform compatibility which
-means the previous interface needs to be deprecated and a new interface
-introduced to replace it. In case the migration to the new interface is trivial,
-the contributor of the change is expected to make good effort to migrate the
-upstream platforms to the new interface.
-
-The `Release information`_ documents the deprecated interfaces and the intended
-release after which it will be removed. When an interface is deprecated, the
-page must be updated to indicate the release after which the interface will be
-removed. This must be at least 1 full release cycle in future. For non-trivial
-interface changes, a `tf-issue`_ should be posted to notify platforms that they
-should migrate away from the deprecated interfaces. Platforms are expected to
-migrate before the removal of the deprecated interface.
-
---------------
-
-*Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _Porting Guide: ./porting-guide.rst
-.. _Release information: https://github.com/ARM-software/arm-trusted-firmware/wiki/TF-A-Release-information#removal-of-deprecated-interfaces
-.. _tf-issue: https://github.com/ARM-software/tf-issues/issues
+++ /dev/null
-Platform Interrupt Controller API documentation
-===============================================
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-This document lists the optional platform interrupt controller API that
-abstracts the runtime configuration and control of interrupt controller from the
-generic code. The mandatory APIs are described in the `porting guide`__.
-
-.. __: porting-guide.rst#interrupt-management-framework-in-bl31
-
-Function: unsigned int plat_ic_get_running_priority(void); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : unsigned int
-
-This API should return the priority of the interrupt the PE is currently
-servicing. This must be be called only after an interrupt has already been
-acknowledged via ``plat_ic_acknowledge_interrupt``.
-
-In the case of Arm standard platforms using GIC, the *Running Priority Register*
-is read to determine the priority of the interrupt.
-
-Function: int plat_ic_is_spi(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : int
-
-The API should return whether the interrupt ID (first parameter) is categorized
-as a Shared Peripheral Interrupt. Shared Peripheral Interrupts are typically
-associated to system-wide peripherals, and these interrupts can target any PE in
-the system.
-
-Function: int plat_ic_is_ppi(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : int
-
-The API should return whether the interrupt ID (first parameter) is categorized
-as a Private Peripheral Interrupt. Private Peripheral Interrupts are typically
-associated with peripherals that are private to each PE. Interrupts from private
-peripherals target to that PE only.
-
-Function: int plat_ic_is_sgi(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : int
-
-The API should return whether the interrupt ID (first parameter) is categorized
-as a Software Generated Interrupt. Software Generated Interrupts are raised by
-explicit programming by software, and are typically used in inter-PE
-communication. Secure SGIs are reserved for use by Secure world software.
-
-Function: unsigned int plat_ic_get_interrupt_active(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : int
-
-This API should return the *active* status of the interrupt ID specified by the
-first parameter, ``id``.
-
-In case of Arm standard platforms using GIC, the implementation of the API reads
-the GIC *Set Active Register* to read and return the active status of the
-interrupt.
-
-Function: void plat_ic_enable_interrupt(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : void
-
-This API should enable the interrupt ID specified by the first parameter,
-``id``. PEs in the system are expected to receive only enabled interrupts.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-inserts barrier to make memory updates visible before enabling interrupt, and
-then writes to GIC *Set Enable Register* to enable the interrupt.
-
-Function: void plat_ic_disable_interrupt(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : void
-
-This API should disable the interrupt ID specified by the first parameter,
-``id``. PEs in the system are not expected to receive disabled interrupts.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-writes to GIC *Clear Enable Register* to disable the interrupt, and inserts
-barrier to make memory updates visible afterwards.
-
-Function: void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Argument : unsigned int
- Return : void
-
-This API should set the priority of the interrupt specified by first parameter
-``id`` to the value set by the second parameter ``priority``.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-writes to GIC *Priority Register* set interrupt priority.
-
-Function: int plat_ic_has_interrupt_type(unsigned int type); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : int
-
-This API should return whether the platform supports a given interrupt type. The
-parameter ``type`` shall be one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1``, or
-``INTR_TYPE_NS``.
-
-In case of Arm standard platforms using GICv3, the implementation of the API
-returns ``1`` for all interrupt types.
-
-In case of Arm standard platforms using GICv2, the API always return ``1`` for
-``INTR_TYPE_NS``. Return value for other types depends on the value of build
-option ``GICV2_G0_FOR_EL3``:
-
-- For interrupt type ``INTR_TYPE_EL3``:
-
- - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns ``0``, indicating no support
- for EL3 interrupts.
-
- - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns ``1``, indicating support for
- EL3 interrupts.
-
-- For interrupt type ``INTR_TYPE_S_EL1``:
-
- - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns ``1``, indicating support for
- Secure EL1 interrupts.
-
- - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns ``0``, indicating no support
- for Secure EL1 interrupts.
-
-Function: void plat_ic_set_interrupt_type(unsigned int id, unsigned int type); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Argument : unsigned int
- Return : void
-
-This API should set the interrupt specified by first parameter ``id`` to the
-type specified by second parameter ``type``. The ``type`` parameter can be
-one of:
-
-- ``INTR_TYPE_NS``: interrupt is meant to be consumed by the Non-secure world.
-
-- ``INTR_TYPE_S_EL1``: interrupt is meant to be consumed by Secure EL1.
-
-- ``INTR_TYPE_EL3``: interrupt is meant to be consumed by EL3.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-writes to the GIC *Group Register* and *Group Modifier Register* (only GICv3) to
-assign the interrupt to the right group.
-
-For GICv3:
-
-- ``INTR_TYPE_NS`` maps to Group 1 interrupt.
-
-- ``INTR_TYPE_S_EL1`` maps to Secure Group 1 interrupt.
-
-- ``INTR_TYPE_EL3`` maps to Secure Group 0 interrupt.
-
-For GICv2:
-
-- ``INTR_TYPE_NS`` maps to Group 1 interrupt.
-
-- When the build option ``GICV2_G0_FOR_EL3`` is set to ``0`` (the default),
- ``INTR_TYPE_S_EL1`` maps to Group 0. Otherwise, ``INTR_TYPE_EL3`` maps to
- Group 0 interrupt.
-
-Function: void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : int
- Argument : u_register_t
- Return : void
-
-This API should raise an EL3 SGI. The first parameter, ``sgi_num``, specifies
-the ID of the SGI. The second parameter, ``target``, must be the MPIDR of the
-target PE.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-inserts barrier to make memory updates visible before raising SGI, then writes
-to appropriate *SGI Register* in order to raise the EL3 SGI.
-
-Function: void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, u_register_t mpidr); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Argument : unsigned int
- Argument : u_register_t
- Return : void
-
-This API should set the routing mode of Share Peripheral Interrupt (SPI)
-specified by first parameter ``id`` to that specified by the second parameter
-``routing_mode``.
-
-The ``routing_mode`` parameter can be one of:
-
-- ``INTR_ROUTING_MODE_ANY`` means the interrupt can be routed to any PE in the
- system. The ``mpidr`` parameter is ignored in this case.
-
-- ``INTR_ROUTING_MODE_PE`` means the interrupt is routed to the PE whose MPIDR
- value is specified by the parameter ``mpidr``.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-writes to the GIC *Target Register* (GICv2) or *Route Register* (GICv3) to set
-the routing.
-
-Function: void plat_ic_set_interrupt_pending(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : void
-
-This API should set the interrupt specified by first parameter ``id`` to
-*Pending*.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-inserts barrier to make memory updates visible before setting interrupt pending,
-and writes to the GIC *Set Pending Register* to set the interrupt pending
-status.
-
-Function: void plat_ic_clear_interrupt_pending(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : void
-
-This API should clear the *Pending* status of the interrupt specified by first
-parameter ``id``.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-writes to the GIC *Clear Pending Register* to clear the interrupt pending
-status, and inserts barrier to make memory updates visible afterwards.
-
-Function: unsigned int plat_ic_set_priority_mask(unsigned int id); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : int
-
-This API should set the priority mask (first parameter) in the interrupt
-controller such that only interrupts of higher priority than the supplied one
-may be signalled to the PE. The API should return the current priority value
-that it's overwriting.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-inserts to order memory updates before updating mask, then writes to the GIC
-*Priority Mask Register*, and make sure memory updates are visible before
-potential trigger due to mask update.
-
-Function: unsigned int plat_ic_get_interrupt_id(unsigned int raw); [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : unsigned int
-
-This API should extract and return the interrupt number from the raw value
-obtained by the acknowledging the interrupt (read using
-``plat_ic_acknowledge_interrupt()``). If the interrupt ID is invalid, this API
-should return ``INTR_ID_UNAVAILABLE``.
-
-In case of Arm standard platforms using GIC, the implementation of the API
-masks out the interrupt ID field from the acknowledged value from GIC.
-
-----
-
-*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
+++ /dev/null
-Trusted Firmware-A Porting Guide
-================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
---------------
-
-Introduction
-------------
-
-Porting Trusted Firmware-A (TF-A) to a new platform involves making some
-mandatory and optional modifications for both the cold and warm boot paths.
-Modifications consist of:
-
-- Implementing a platform-specific function or variable,
-- Setting up the execution context in a certain way, or
-- Defining certain constants (for example #defines).
-
-The platform-specific functions and variables are declared in
-`include/plat/common/platform.h`_. The firmware provides a default implementation
-of variables and functions to fulfill the optional requirements. These
-implementations are all weakly defined; they are provided to ease the porting
-effort. Each platform port can override them with its own implementation if the
-default implementation is inadequate.
-
-Some modifications are common to all Boot Loader (BL) stages. Section 2
-discusses these in detail. The subsequent sections discuss the remaining
-modifications for each BL stage in detail.
-
-This document should be read in conjunction with the TF-A `User Guide`_.
-
-Please refer to the `Platform compatibility policy`_ for the policy regarding
-compatibility and deprecation of these porting interfaces.
-
-Only Arm development platforms (such as FVP and Juno) may use the
-functions/definitions in ``include/plat/arm/common/`` and the corresponding
-source files in ``plat/arm/common/``. This is done so that there are no
-dependencies between platforms maintained by different people/companies. If you
-want to use any of the functionality present in ``plat/arm`` files, please
-create a pull request that moves the code to ``plat/common`` so that it can be
-discussed.
-
-Common modifications
---------------------
-
-This section covers the modifications that should be made by the platform for
-each BL stage to correctly port the firmware stack. They are categorized as
-either mandatory or optional.
-
-Common mandatory modifications
-------------------------------
-
-A platform port must enable the Memory Management Unit (MMU) as well as the
-instruction and data caches for each BL stage. Setting up the translation
-tables is the responsibility of the platform port because memory maps differ
-across platforms. A memory translation library (see ``lib/xlat_tables/``) is
-provided to help in this setup.
-
-Note that although this library supports non-identity mappings, this is intended
-only for re-mapping peripheral physical addresses and allows platforms with high
-I/O addresses to reduce their virtual address space. All other addresses
-corresponding to code and data must currently use an identity mapping.
-
-Also, the only translation granule size supported in TF-A is 4KB, as various
-parts of the code assume that is the case. It is not possible to switch to
-16 KB or 64 KB granule sizes at the moment.
-
-In Arm standard platforms, each BL stage configures the MMU in the
-platform-specific architecture setup function, ``blX_plat_arch_setup()``, and uses
-an identity mapping for all addresses.
-
-If the build option ``USE_COHERENT_MEM`` is enabled, each platform can allocate a
-block of identity mapped secure memory with Device-nGnRE attributes aligned to
-page boundary (4K) for each BL stage. All sections which allocate coherent
-memory are grouped under ``coherent_ram``. For ex: Bakery locks are placed in a
-section identified by name ``bakery_lock`` inside ``coherent_ram`` so that its
-possible for the firmware to place variables in it using the following C code
-directive:
-
-::
-
- __section("bakery_lock")
-
-Or alternatively the following assembler code directive:
-
-::
-
- .section bakery_lock
-
-The ``coherent_ram`` section is a sum of all sections like ``bakery_lock`` which are
-used to allocate any data structures that are accessed both when a CPU is
-executing with its MMU and caches enabled, and when it's running with its MMU
-and caches disabled. Examples are given below.
-
-The following variables, functions and constants must be defined by the platform
-for the firmware to work correctly.
-
-File : platform_def.h [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Each platform must ensure that a header file of this name is in the system
-include path with the following constants defined. This will require updating
-the list of ``PLAT_INCLUDES`` in the ``platform.mk`` file.
-
-Platform ports may optionally use the file `include/plat/common/common_def.h`_,
-which provides typical values for some of the constants below. These values are
-likely to be suitable for all platform ports.
-
-- **#define : PLATFORM_LINKER_FORMAT**
-
- Defines the linker format used by the platform, for example
- ``elf64-littleaarch64``.
-
-- **#define : PLATFORM_LINKER_ARCH**
-
- Defines the processor architecture for the linker by the platform, for
- example ``aarch64``.
-
-- **#define : PLATFORM_STACK_SIZE**
-
- Defines the normal stack memory available to each CPU. This constant is used
- by `plat/common/aarch64/platform_mp_stack.S`_ and
- `plat/common/aarch64/platform_up_stack.S`_.
-
-- **define : CACHE_WRITEBACK_GRANULE**
-
- Defines the size in bits of the largest cache line across all the cache
- levels in the platform.
-
-- **#define : FIRMWARE_WELCOME_STR**
-
- Defines the character string printed by BL1 upon entry into the ``bl1_main()``
- function.
-
-- **#define : PLATFORM_CORE_COUNT**
-
- Defines the total number of CPUs implemented by the platform across all
- clusters in the system.
-
-- **#define : PLAT_NUM_PWR_DOMAINS**
-
- Defines the total number of nodes in the power domain topology
- tree at all the power domain levels used by the platform.
- This macro is used by the PSCI implementation to allocate
- data structures to represent power domain topology.
-
-- **#define : PLAT_MAX_PWR_LVL**
-
- Defines the maximum power domain level that the power management operations
- should apply to. More often, but not always, the power domain level
- corresponds to affinity level. This macro allows the PSCI implementation
- to know the highest power domain level that it should consider for power
- management operations in the system that the platform implements. For
- example, the Base AEM FVP implements two clusters with a configurable
- number of CPUs and it reports the maximum power domain level as 1.
-
-- **#define : PLAT_MAX_OFF_STATE**
-
- Defines the local power state corresponding to the deepest power down
- possible at every power domain level in the platform. The local power
- states for each level may be sparsely allocated between 0 and this value
- with 0 being reserved for the RUN state. The PSCI implementation uses this
- value to initialize the local power states of the power domain nodes and
- to specify the requested power state for a PSCI_CPU_OFF call.
-
-- **#define : PLAT_MAX_RET_STATE**
-
- Defines the local power state corresponding to the deepest retention state
- possible at every power domain level in the platform. This macro should be
- a value less than PLAT_MAX_OFF_STATE and greater than 0. It is used by the
- PSCI implementation to distinguish between retention and power down local
- power states within PSCI_CPU_SUSPEND call.
-
-- **#define : PLAT_MAX_PWR_LVL_STATES**
-
- Defines the maximum number of local power states per power domain level
- that the platform supports. The default value of this macro is 2 since
- most platforms just support a maximum of two local power states at each
- power domain level (power-down and retention). If the platform needs to
- account for more local power states, then it must redefine this macro.
-
- Currently, this macro is used by the Generic PSCI implementation to size
- the array used for PSCI_STAT_COUNT/RESIDENCY accounting.
-
-- **#define : BL1_RO_BASE**
-
- Defines the base address in secure ROM where BL1 originally lives. Must be
- aligned on a page-size boundary.
-
-- **#define : BL1_RO_LIMIT**
-
- Defines the maximum address in secure ROM that BL1's actual content (i.e.
- excluding any data section allocated at runtime) can occupy.
-
-- **#define : BL1_RW_BASE**
-
- Defines the base address in secure RAM where BL1's read-write data will live
- at runtime. Must be aligned on a page-size boundary.
-
-- **#define : BL1_RW_LIMIT**
-
- Defines the maximum address in secure RAM that BL1's read-write data can
- occupy at runtime.
-
-- **#define : BL2_BASE**
-
- Defines the base address in secure RAM where BL1 loads the BL2 binary image.
- Must be aligned on a page-size boundary. This constant is not applicable
- when BL2_IN_XIP_MEM is set to '1'.
-
-- **#define : BL2_LIMIT**
-
- Defines the maximum address in secure RAM that the BL2 image can occupy.
- This constant is not applicable when BL2_IN_XIP_MEM is set to '1'.
-
-- **#define : BL2_RO_BASE**
-
- Defines the base address in secure XIP memory where BL2 RO section originally
- lives. Must be aligned on a page-size boundary. This constant is only needed
- when BL2_IN_XIP_MEM is set to '1'.
-
-- **#define : BL2_RO_LIMIT**
-
- Defines the maximum address in secure XIP memory that BL2's actual content
- (i.e. excluding any data section allocated at runtime) can occupy. This
- constant is only needed when BL2_IN_XIP_MEM is set to '1'.
-
-- **#define : BL2_RW_BASE**
-
- Defines the base address in secure RAM where BL2's read-write data will live
- at runtime. Must be aligned on a page-size boundary. This constant is only
- needed when BL2_IN_XIP_MEM is set to '1'.
-
-- **#define : BL2_RW_LIMIT**
-
- Defines the maximum address in secure RAM that BL2's read-write data can
- occupy at runtime. This constant is only needed when BL2_IN_XIP_MEM is set
- to '1'.
-
-- **#define : BL31_BASE**
-
- Defines the base address in secure RAM where BL2 loads the BL31 binary
- image. Must be aligned on a page-size boundary.
-
-- **#define : BL31_LIMIT**
-
- Defines the maximum address in secure RAM that the BL31 image can occupy.
-
-For every image, the platform must define individual identifiers that will be
-used by BL1 or BL2 to load the corresponding image into memory from non-volatile
-storage. For the sake of performance, integer numbers will be used as
-identifiers. The platform will use those identifiers to return the relevant
-information about the image to be loaded (file handler, load address,
-authentication information, etc.). The following image identifiers are
-mandatory:
-
-- **#define : BL2_IMAGE_ID**
-
- BL2 image identifier, used by BL1 to load BL2.
-
-- **#define : BL31_IMAGE_ID**
-
- BL31 image identifier, used by BL2 to load BL31.
-
-- **#define : BL33_IMAGE_ID**
-
- BL33 image identifier, used by BL2 to load BL33.
-
-If Trusted Board Boot is enabled, the following certificate identifiers must
-also be defined:
-
-- **#define : TRUSTED_BOOT_FW_CERT_ID**
-
- BL2 content certificate identifier, used by BL1 to load the BL2 content
- certificate.
-
-- **#define : TRUSTED_KEY_CERT_ID**
-
- Trusted key certificate identifier, used by BL2 to load the trusted key
- certificate.
-
-- **#define : SOC_FW_KEY_CERT_ID**
-
- BL31 key certificate identifier, used by BL2 to load the BL31 key
- certificate.
-
-- **#define : SOC_FW_CONTENT_CERT_ID**
-
- BL31 content certificate identifier, used by BL2 to load the BL31 content
- certificate.
-
-- **#define : NON_TRUSTED_FW_KEY_CERT_ID**
-
- BL33 key certificate identifier, used by BL2 to load the BL33 key
- certificate.
-
-- **#define : NON_TRUSTED_FW_CONTENT_CERT_ID**
-
- BL33 content certificate identifier, used by BL2 to load the BL33 content
- certificate.
-
-- **#define : FWU_CERT_ID**
-
- Firmware Update (FWU) certificate identifier, used by NS_BL1U to load the
- FWU content certificate.
-
-- **#define : PLAT_CRYPTOCELL_BASE**
-
- This defines the base address of Arm® TrustZone® CryptoCell and must be
- defined if CryptoCell crypto driver is used for Trusted Board Boot. For
- capable Arm platforms, this driver is used if ``ARM_CRYPTOCELL_INTEG`` is
- set.
-
-If the AP Firmware Updater Configuration image, BL2U is used, the following
-must also be defined:
-
-- **#define : BL2U_BASE**
-
- Defines the base address in secure memory where BL1 copies the BL2U binary
- image. Must be aligned on a page-size boundary.
-
-- **#define : BL2U_LIMIT**
-
- Defines the maximum address in secure memory that the BL2U image can occupy.
-
-- **#define : BL2U_IMAGE_ID**
-
- BL2U image identifier, used by BL1 to fetch an image descriptor
- corresponding to BL2U.
-
-If the SCP Firmware Update Configuration Image, SCP_BL2U is used, the following
-must also be defined:
-
-- **#define : SCP_BL2U_IMAGE_ID**
-
- SCP_BL2U image identifier, used by BL1 to fetch an image descriptor
- corresponding to SCP_BL2U.
- NOTE: TF-A does not provide source code for this image.
-
-If the Non-Secure Firmware Updater ROM, NS_BL1U is used, the following must
-also be defined:
-
-- **#define : NS_BL1U_BASE**
-
- Defines the base address in non-secure ROM where NS_BL1U executes.
- Must be aligned on a page-size boundary.
- NOTE: TF-A does not provide source code for this image.
-
-- **#define : NS_BL1U_IMAGE_ID**
-
- NS_BL1U image identifier, used by BL1 to fetch an image descriptor
- corresponding to NS_BL1U.
-
-If the Non-Secure Firmware Updater, NS_BL2U is used, the following must also
-be defined:
-
-- **#define : NS_BL2U_BASE**
-
- Defines the base address in non-secure memory where NS_BL2U executes.
- Must be aligned on a page-size boundary.
- NOTE: TF-A does not provide source code for this image.
-
-- **#define : NS_BL2U_IMAGE_ID**
-
- NS_BL2U image identifier, used by BL1 to fetch an image descriptor
- corresponding to NS_BL2U.
-
-For the the Firmware update capability of TRUSTED BOARD BOOT, the following
-macros may also be defined:
-
-- **#define : PLAT_FWU_MAX_SIMULTANEOUS_IMAGES**
-
- Total number of images that can be loaded simultaneously. If the platform
- doesn't specify any value, it defaults to 10.
-
-If a SCP_BL2 image is supported by the platform, the following constants must
-also be defined:
-
-- **#define : SCP_BL2_IMAGE_ID**
-
- SCP_BL2 image identifier, used by BL2 to load SCP_BL2 into secure memory
- from platform storage before being transferred to the SCP.
-
-- **#define : SCP_FW_KEY_CERT_ID**
-
- SCP_BL2 key certificate identifier, used by BL2 to load the SCP_BL2 key
- certificate (mandatory when Trusted Board Boot is enabled).
-
-- **#define : SCP_FW_CONTENT_CERT_ID**
-
- SCP_BL2 content certificate identifier, used by BL2 to load the SCP_BL2
- content certificate (mandatory when Trusted Board Boot is enabled).
-
-If a BL32 image is supported by the platform, the following constants must
-also be defined:
-
-- **#define : BL32_IMAGE_ID**
-
- BL32 image identifier, used by BL2 to load BL32.
-
-- **#define : TRUSTED_OS_FW_KEY_CERT_ID**
-
- BL32 key certificate identifier, used by BL2 to load the BL32 key
- certificate (mandatory when Trusted Board Boot is enabled).
-
-- **#define : TRUSTED_OS_FW_CONTENT_CERT_ID**
-
- BL32 content certificate identifier, used by BL2 to load the BL32 content
- certificate (mandatory when Trusted Board Boot is enabled).
-
-- **#define : BL32_BASE**
-
- Defines the base address in secure memory where BL2 loads the BL32 binary
- image. Must be aligned on a page-size boundary.
-
-- **#define : BL32_LIMIT**
-
- Defines the maximum address that the BL32 image can occupy.
-
-If the Test Secure-EL1 Payload (TSP) instantiation of BL32 is supported by the
-platform, the following constants must also be defined:
-
-- **#define : TSP_SEC_MEM_BASE**
-
- Defines the base address of the secure memory used by the TSP image on the
- platform. This must be at the same address or below ``BL32_BASE``.
-
-- **#define : TSP_SEC_MEM_SIZE**
-
- Defines the size of the secure memory used by the BL32 image on the
- platform. ``TSP_SEC_MEM_BASE`` and ``TSP_SEC_MEM_SIZE`` must fully
- accommodate the memory required by the BL32 image, defined by ``BL32_BASE``
- and ``BL32_LIMIT``.
-
-- **#define : TSP_IRQ_SEC_PHY_TIMER**
-
- Defines the ID of the secure physical generic timer interrupt used by the
- TSP's interrupt handling code.
-
-If the platform port uses the translation table library code, the following
-constants must also be defined:
-
-- **#define : PLAT_XLAT_TABLES_DYNAMIC**
-
- Optional flag that can be set per-image to enable the dynamic allocation of
- regions even when the MMU is enabled. If not defined, only static
- functionality will be available, if defined and set to 1 it will also
- include the dynamic functionality.
-
-- **#define : MAX_XLAT_TABLES**
-
- Defines the maximum number of translation tables that are allocated by the
- translation table library code. To minimize the amount of runtime memory
- used, choose the smallest value needed to map the required virtual addresses
- for each BL stage. If ``PLAT_XLAT_TABLES_DYNAMIC`` flag is enabled for a BL
- image, ``MAX_XLAT_TABLES`` must be defined to accommodate the dynamic regions
- as well.
-
-- **#define : MAX_MMAP_REGIONS**
-
- Defines the maximum number of regions that are allocated by the translation
- table library code. A region consists of physical base address, virtual base
- address, size and attributes (Device/Memory, RO/RW, Secure/Non-Secure), as
- defined in the ``mmap_region_t`` structure. The platform defines the regions
- that should be mapped. Then, the translation table library will create the
- corresponding tables and descriptors at runtime. To minimize the amount of
- runtime memory used, choose the smallest value needed to register the
- required regions for each BL stage. If ``PLAT_XLAT_TABLES_DYNAMIC`` flag is
- enabled for a BL image, ``MAX_MMAP_REGIONS`` must be defined to accommodate
- the dynamic regions as well.
-
-- **#define : PLAT_VIRT_ADDR_SPACE_SIZE**
-
- Defines the total size of the virtual address space in bytes. For example,
- for a 32 bit virtual address space, this value should be ``(1ULL << 32)``.
-
-- **#define : PLAT_PHY_ADDR_SPACE_SIZE**
-
- Defines the total size of the physical address space in bytes. For example,
- for a 32 bit physical address space, this value should be ``(1ULL << 32)``.
-
-If the platform port uses the IO storage framework, the following constants
-must also be defined:
-
-- **#define : MAX_IO_DEVICES**
-
- Defines the maximum number of registered IO devices. Attempting to register
- more devices than this value using ``io_register_device()`` will fail with
- -ENOMEM.
-
-- **#define : MAX_IO_HANDLES**
-
- Defines the maximum number of open IO handles. Attempting to open more IO
- entities than this value using ``io_open()`` will fail with -ENOMEM.
-
-- **#define : MAX_IO_BLOCK_DEVICES**
-
- Defines the maximum number of registered IO block devices. Attempting to
- register more devices this value using ``io_dev_open()`` will fail
- with -ENOMEM. MAX_IO_BLOCK_DEVICES should be less than MAX_IO_DEVICES.
- With this macro, multiple block devices could be supported at the same
- time.
-
-If the platform needs to allocate data within the per-cpu data framework in
-BL31, it should define the following macro. Currently this is only required if
-the platform decides not to use the coherent memory section by undefining the
-``USE_COHERENT_MEM`` build flag. In this case, the framework allocates the
-required memory within the the per-cpu data to minimize wastage.
-
-- **#define : PLAT_PCPU_DATA_SIZE**
-
- Defines the memory (in bytes) to be reserved within the per-cpu data
- structure for use by the platform layer.
-
-The following constants are optional. They should be defined when the platform
-memory layout implies some image overlaying like in Arm standard platforms.
-
-- **#define : BL31_PROGBITS_LIMIT**
-
- Defines the maximum address in secure RAM that the BL31's progbits sections
- can occupy.
-
-- **#define : TSP_PROGBITS_LIMIT**
-
- Defines the maximum address that the TSP's progbits sections can occupy.
-
-If the platform port uses the PL061 GPIO driver, the following constant may
-optionally be defined:
-
-- **PLAT_PL061_MAX_GPIOS**
- Maximum number of GPIOs required by the platform. This allows control how
- much memory is allocated for PL061 GPIO controllers. The default value is
-
- #. $(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
-
-If the platform port uses the partition driver, the following constant may
-optionally be defined:
-
-- **PLAT_PARTITION_MAX_ENTRIES**
- Maximum number of partition entries required by the platform. This allows
- control how much memory is allocated for partition entries. The default
- value is 128.
- `For example, define the build flag in platform.mk`_:
- PLAT_PARTITION_MAX_ENTRIES := 12
- $(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
-
-The following constant is optional. It should be defined to override the default
-behaviour of the ``assert()`` function (for example, to save memory).
-
-- **PLAT_LOG_LEVEL_ASSERT**
- If ``PLAT_LOG_LEVEL_ASSERT`` is higher or equal than ``LOG_LEVEL_VERBOSE``,
- ``assert()`` prints the name of the file, the line number and the asserted
- expression. Else if it is higher than ``LOG_LEVEL_INFO``, it prints the file
- name and the line number. Else if it is lower than ``LOG_LEVEL_INFO``, it
- doesn't print anything to the console. If ``PLAT_LOG_LEVEL_ASSERT`` isn't
- defined, it defaults to ``LOG_LEVEL``.
-
-If the platform port uses the Activity Monitor Unit, the following constants
-may be defined:
-
-- **PLAT_AMU_GROUP1_COUNTERS_MASK**
- This mask reflects the set of group counters that should be enabled. The
- maximum number of group 1 counters supported by AMUv1 is 16 so the mask
- can be at most 0xffff. If the platform does not define this mask, no group 1
- counters are enabled. If the platform defines this mask, the following
- constant needs to also be defined.
-
-- **PLAT_AMU_GROUP1_NR_COUNTERS**
- This value is used to allocate an array to save and restore the counters
- specified by ``PLAT_AMU_GROUP1_COUNTERS_MASK`` on CPU suspend.
- This value should be equal to the highest bit position set in the
- mask, plus 1. The maximum number of group 1 counters in AMUv1 is 16.
-
-File : plat_macros.S [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Each platform must ensure a file of this name is in the system include path with
-the following macro defined. In the Arm development platforms, this file is
-found in ``plat/arm/board/<plat_name>/include/plat_macros.S``.
-
-- **Macro : plat_crash_print_regs**
-
- This macro allows the crash reporting routine to print relevant platform
- registers in case of an unhandled exception in BL31. This aids in debugging
- and this macro can be defined to be empty in case register reporting is not
- desired.
-
- For instance, GIC or interconnect registers may be helpful for
- troubleshooting.
-
-Handling Reset
---------------
-
-BL1 by default implements the reset vector where execution starts from a cold
-or warm boot. BL31 can be optionally set as a reset vector using the
-``RESET_TO_BL31`` make variable.
-
-For each CPU, the reset vector code is responsible for the following tasks:
-
-#. Distinguishing between a cold boot and a warm boot.
-
-#. In the case of a cold boot and the CPU being a secondary CPU, ensuring that
- the CPU is placed in a platform-specific state until the primary CPU
- performs the necessary steps to remove it from this state.
-
-#. In the case of a warm boot, ensuring that the CPU jumps to a platform-
- specific address in the BL31 image in the same processor mode as it was
- when released from reset.
-
-The following functions need to be implemented by the platform port to enable
-reset vector code to perform the above tasks.
-
-Function : plat_get_my_entrypoint() [mandatory when PROGRAMMABLE_RESET_ADDRESS == 0]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : uintptr_t
-
-This function is called with the MMU and caches disabled
-(``SCTLR_EL3.M`` = 0 and ``SCTLR_EL3.C`` = 0). The function is responsible for
-distinguishing between a warm and cold reset for the current CPU using
-platform-specific means. If it's a warm reset, then it returns the warm
-reset entrypoint point provided to ``plat_setup_psci_ops()`` during
-BL31 initialization. If it's a cold reset then this function must return zero.
-
-This function does not follow the Procedure Call Standard used by the
-Application Binary Interface for the Arm 64-bit architecture. The caller should
-not assume that callee saved registers are preserved across a call to this
-function.
-
-This function fulfills requirement 1 and 3 listed above.
-
-Note that for platforms that support programming the reset address, it is
-expected that a CPU will start executing code directly at the right address,
-both on a cold and warm reset. In this case, there is no need to identify the
-type of reset nor to query the warm reset entrypoint. Therefore, implementing
-this function is not required on such platforms.
-
-Function : plat_secondary_cold_boot_setup() [mandatory when COLD_BOOT_SINGLE_CPU == 0]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
-
-This function is called with the MMU and data caches disabled. It is responsible
-for placing the executing secondary CPU in a platform-specific state until the
-primary CPU performs the necessary actions to bring it out of that state and
-allow entry into the OS. This function must not return.
-
-In the Arm FVP port, when using the normal boot flow, each secondary CPU powers
-itself off. The primary CPU is responsible for powering up the secondary CPUs
-when normal world software requires them. When booting an EL3 payload instead,
-they stay powered on and are put in a holding pen until their mailbox gets
-populated.
-
-This function fulfills requirement 2 above.
-
-Note that for platforms that can't release secondary CPUs out of reset, only the
-primary CPU will execute the cold boot code. Therefore, implementing this
-function is not required on such platforms.
-
-Function : plat_is_my_cpu_primary() [mandatory when COLD_BOOT_SINGLE_CPU == 0]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : unsigned int
-
-This function identifies whether the current CPU is the primary CPU or a
-secondary CPU. A return value of zero indicates that the CPU is not the
-primary CPU, while a non-zero return value indicates that the CPU is the
-primary CPU.
-
-Note that for platforms that can't release secondary CPUs out of reset, only the
-primary CPU will execute the cold boot code. Therefore, there is no need to
-distinguish between primary and secondary CPUs and implementing this function is
-not required.
-
-Function : platform_mem_init() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function is called before any access to data is made by the firmware, in
-order to carry out any essential memory initialization.
-
-Function: plat_get_rotpk_info()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void *, void **, unsigned int *, unsigned int *
- Return : int
-
-This function is mandatory when Trusted Board Boot is enabled. It returns a
-pointer to the ROTPK stored in the platform (or a hash of it) and its length.
-The ROTPK must be encoded in DER format according to the following ASN.1
-structure:
-
-::
-
- AlgorithmIdentifier ::= SEQUENCE {
- algorithm OBJECT IDENTIFIER,
- parameters ANY DEFINED BY algorithm OPTIONAL
- }
-
- SubjectPublicKeyInfo ::= SEQUENCE {
- algorithm AlgorithmIdentifier,
- subjectPublicKey BIT STRING
- }
-
-In case the function returns a hash of the key:
-
-::
-
- DigestInfo ::= SEQUENCE {
- digestAlgorithm AlgorithmIdentifier,
- digest OCTET STRING
- }
-
-The function returns 0 on success. Any other value is treated as error by the
-Trusted Board Boot. The function also reports extra information related
-to the ROTPK in the flags parameter:
-
-::
-
- ROTPK_IS_HASH : Indicates that the ROTPK returned by the platform is a
- hash.
- ROTPK_NOT_DEPLOYED : This allows the platform to skip certificate ROTPK
- verification while the platform ROTPK is not deployed.
- When this flag is set, the function does not need to
- return a platform ROTPK, and the authentication
- framework uses the ROTPK in the certificate without
- verifying it against the platform value. This flag
- must not be used in a deployed production environment.
-
-Function: plat_get_nv_ctr()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void *, unsigned int *
- Return : int
-
-This function is mandatory when Trusted Board Boot is enabled. It returns the
-non-volatile counter value stored in the platform in the second argument. The
-cookie in the first argument may be used to select the counter in case the
-platform provides more than one (for example, on platforms that use the default
-TBBR CoT, the cookie will correspond to the OID values defined in
-TRUSTED_FW_NVCOUNTER_OID or NON_TRUSTED_FW_NVCOUNTER_OID).
-
-The function returns 0 on success. Any other value means the counter value could
-not be retrieved from the platform.
-
-Function: plat_set_nv_ctr()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void *, unsigned int
- Return : int
-
-This function is mandatory when Trusted Board Boot is enabled. It sets a new
-counter value in the platform. The cookie in the first argument may be used to
-select the counter (as explained in plat_get_nv_ctr()). The second argument is
-the updated counter value to be written to the NV counter.
-
-The function returns 0 on success. Any other value means the counter value could
-not be updated.
-
-Function: plat_set_nv_ctr2()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void *, const auth_img_desc_t *, unsigned int
- Return : int
-
-This function is optional when Trusted Board Boot is enabled. If this
-interface is defined, then ``plat_set_nv_ctr()`` need not be defined. The
-first argument passed is a cookie and is typically used to
-differentiate between a Non Trusted NV Counter and a Trusted NV
-Counter. The second argument is a pointer to an authentication image
-descriptor and may be used to decide if the counter is allowed to be
-updated or not. The third argument is the updated counter value to
-be written to the NV counter.
-
-The function returns 0 on success. Any other value means the counter value
-either could not be updated or the authentication image descriptor indicates
-that it is not allowed to be updated.
-
-Common mandatory function modifications
----------------------------------------
-
-The following functions are mandatory functions which need to be implemented
-by the platform port.
-
-Function : plat_my_core_pos()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : unsigned int
-
-This function returns the index of the calling CPU which is used as a
-CPU-specific linear index into blocks of memory (for example while allocating
-per-CPU stacks). This function will be invoked very early in the
-initialization sequence which mandates that this function should be
-implemented in assembly and should not rely on the availability of a C
-runtime environment. This function can clobber x0 - x8 and must preserve
-x9 - x29.
-
-This function plays a crucial role in the power domain topology framework in
-PSCI and details of this can be found in `Power Domain Topology Design`_.
-
-Function : plat_core_pos_by_mpidr()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : u_register_t
- Return : int
-
-This function validates the ``MPIDR`` of a CPU and converts it to an index,
-which can be used as a CPU-specific linear index into blocks of memory. In
-case the ``MPIDR`` is invalid, this function returns -1. This function will only
-be invoked by BL31 after the power domain topology is initialized and can
-utilize the C runtime environment. For further details about how TF-A
-represents the power domain topology and how this relates to the linear CPU
-index, please refer `Power Domain Topology Design`_.
-
-Function : plat_get_mbedtls_heap() [when TRUSTED_BOARD_BOOT == 1]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Arguments : void **heap_addr, size_t *heap_size
- Return : int
-
-This function is invoked during Mbed TLS library initialisation to get a heap,
-by means of a starting address and a size. This heap will then be used
-internally by the Mbed TLS library. Hence, each BL stage that utilises Mbed TLS
-must be able to provide a heap to it.
-
-A helper function can be found in `drivers/auth/mbedtls/mbedtls_common.c` in
-which a heap is statically reserved during compile time inside every image
-(i.e. every BL stage) that utilises Mbed TLS. In this default implementation,
-the function simply returns the address and size of this "pre-allocated" heap.
-For a platform to use this default implementation, only a call to the helper
-from inside plat_get_mbedtls_heap() body is enough and nothing else is needed.
-
-However, by writting their own implementation, platforms have the potential to
-optimise memory usage. For example, on some Arm platforms, the Mbed TLS heap is
-shared between BL1 and BL2 stages and, thus, the necessary space is not reserved
-twice.
-
-On success the function should return 0 and a negative error code otherwise.
-
-Common optional modifications
------------------------------
-
-The following are helper functions implemented by the firmware that perform
-common platform-specific tasks. A platform may choose to override these
-definitions.
-
-Function : plat_set_my_stack()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function sets the current stack pointer to the normal memory stack that
-has been allocated for the current CPU. For BL images that only require a
-stack for the primary CPU, the UP version of the function is used. The size
-of the stack allocated to each CPU is specified by the platform defined
-constant ``PLATFORM_STACK_SIZE``.
-
-Common implementations of this function for the UP and MP BL images are
-provided in `plat/common/aarch64/platform_up_stack.S`_ and
-`plat/common/aarch64/platform_mp_stack.S`_
-
-Function : plat_get_my_stack()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : uintptr_t
-
-This function returns the base address of the normal memory stack that
-has been allocated for the current CPU. For BL images that only require a
-stack for the primary CPU, the UP version of the function is used. The size
-of the stack allocated to each CPU is specified by the platform defined
-constant ``PLATFORM_STACK_SIZE``.
-
-Common implementations of this function for the UP and MP BL images are
-provided in `plat/common/aarch64/platform_up_stack.S`_ and
-`plat/common/aarch64/platform_mp_stack.S`_
-
-Function : plat_report_exception()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : void
-
-A platform may need to report various information about its status when an
-exception is taken, for example the current exception level, the CPU security
-state (secure/non-secure), the exception type, and so on. This function is
-called in the following circumstances:
-
-- In BL1, whenever an exception is taken.
-- In BL2, whenever an exception is taken.
-
-The default implementation doesn't do anything, to avoid making assumptions
-about the way the platform displays its status information.
-
-For AArch64, this function receives the exception type as its argument.
-Possible values for exceptions types are listed in the
-`include/common/bl_common.h`_ header file. Note that these constants are not
-related to any architectural exception code; they are just a TF-A convention.
-
-For AArch32, this function receives the exception mode as its argument.
-Possible values for exception modes are listed in the
-`include/lib/aarch32/arch.h`_ header file.
-
-Function : plat_reset_handler()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-A platform may need to do additional initialization after reset. This function
-allows the platform to do the platform specific intializations. Platform
-specific errata workarounds could also be implemented here. The API should
-preserve the values of callee saved registers x19 to x29.
-
-The default implementation doesn't do anything. If a platform needs to override
-the default implementation, refer to the `Firmware Design`_ for general
-guidelines.
-
-Function : plat_disable_acp()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This API allows a platform to disable the Accelerator Coherency Port (if
-present) during a cluster power down sequence. The default weak implementation
-doesn't do anything. Since this API is called during the power down sequence,
-it has restrictions for stack usage and it can use the registers x0 - x17 as
-scratch registers. It should preserve the value in x18 register as it is used
-by the caller to store the return address.
-
-Function : plat_error_handler()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : int
- Return : void
-
-This API is called when the generic code encounters an error situation from
-which it cannot continue. It allows the platform to perform error reporting or
-recovery actions (for example, reset the system). This function must not return.
-
-The parameter indicates the type of error using standard codes from ``errno.h``.
-Possible errors reported by the generic code are:
-
-- ``-EAUTH``: a certificate or image could not be authenticated (when Trusted
- Board Boot is enabled)
-- ``-ENOENT``: the requested image or certificate could not be found or an IO
- error was detected
-- ``-ENOMEM``: resources exhausted. TF-A does not use dynamic memory, so this
- error is usually an indication of an incorrect array size
-
-The default implementation simply spins.
-
-Function : plat_panic_handler()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This API is called when the generic code encounters an unexpected error
-situation from which it cannot recover. This function must not return,
-and must be implemented in assembly because it may be called before the C
-environment is initialized.
-
-Note: The address from where it was called is stored in x30 (Link Register).
-The default implementation simply spins.
-
-Function : plat_get_bl_image_load_info()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : bl_load_info_t *
-
-This function returns pointer to the list of images that the platform has
-populated to load. This function is invoked in BL2 to load the
-BL3xx images.
-
-Function : plat_get_next_bl_params()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : bl_params_t *
-
-This function returns a pointer to the shared memory that the platform has
-kept aside to pass TF-A related information that next BL image needs. This
-function is invoked in BL2 to pass this information to the next BL
-image.
-
-Function : plat_get_stack_protector_canary()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : u_register_t
-
-This function returns a random value that is used to initialize the canary used
-when the stack protector is enabled with ENABLE_STACK_PROTECTOR. A predictable
-value will weaken the protection as the attacker could easily write the right
-value as part of the attack most of the time. Therefore, it should return a
-true random number.
-
-Note: For the protection to be effective, the global data need to be placed at
-a lower address than the stack bases. Failure to do so would allow an attacker
-to overwrite the canary as part of the stack buffer overflow attack.
-
-Function : plat_flush_next_bl_params()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function flushes to main memory all the image params that are passed to
-next image. This function is invoked in BL2 to flush this information
-to the next BL image.
-
-Function : plat_log_get_prefix()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : const char *
-
-This function defines the prefix string corresponding to the `log_level` to be
-prepended to all the log output from TF-A. The `log_level` (argument) will
-correspond to one of the standard log levels defined in debug.h. The platform
-can override the common implementation to define a different prefix string for
-the log output. The implementation should be robust to future changes that
-increase the number of log levels.
-
-Modifications specific to a Boot Loader stage
----------------------------------------------
-
-Boot Loader Stage 1 (BL1)
--------------------------
-
-BL1 implements the reset vector where execution starts from after a cold or
-warm boot. For each CPU, BL1 is responsible for the following tasks:
-
-#. Handling the reset as described in section 2.2
-
-#. In the case of a cold boot and the CPU being the primary CPU, ensuring that
- only this CPU executes the remaining BL1 code, including loading and passing
- control to the BL2 stage.
-
-#. Identifying and starting the Firmware Update process (if required).
-
-#. Loading the BL2 image from non-volatile storage into secure memory at the
- address specified by the platform defined constant ``BL2_BASE``.
-
-#. Populating a ``meminfo`` structure with the following information in memory,
- accessible by BL2 immediately upon entry.
-
- ::
-
- meminfo.total_base = Base address of secure RAM visible to BL2
- meminfo.total_size = Size of secure RAM visible to BL2
-
- By default, BL1 places this ``meminfo`` structure at the end of secure
- memory visible to BL2.
-
- It is possible for the platform to decide where it wants to place the
- ``meminfo`` structure for BL2 or restrict the amount of memory visible to
- BL2 by overriding the weak default implementation of
- ``bl1_plat_handle_post_image_load`` API.
-
-The following functions need to be implemented by the platform port to enable
-BL1 to perform the above tasks.
-
-Function : bl1_early_platform_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only called
-by the primary CPU.
-
-On Arm standard platforms, this function:
-
-- Enables a secure instance of SP805 to act as the Trusted Watchdog.
-
-- Initializes a UART (PL011 console), which enables access to the ``printf``
- family of functions in BL1.
-
-- Enables issuing of snoop and DVM (Distributed Virtual Memory) requests to
- the CCI slave interface corresponding to the cluster that includes the
- primary CPU.
-
-Function : bl1_plat_arch_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function performs any platform-specific and architectural setup that the
-platform requires. Platform-specific setup might include configuration of
-memory controllers and the interconnect.
-
-In Arm standard platforms, this function enables the MMU.
-
-This function helps fulfill requirement 2 above.
-
-Function : bl1_platform_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function executes with the MMU and data caches enabled. It is responsible
-for performing any remaining platform-specific setup that can occur after the
-MMU and data cache have been enabled.
-
-if support for multiple boot sources is required, it initializes the boot
-sequence used by plat_try_next_boot_source().
-
-In Arm standard platforms, this function initializes the storage abstraction
-layer used to load the next bootloader image.
-
-This function helps fulfill requirement 4 above.
-
-Function : bl1_plat_sec_mem_layout() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : meminfo *
-
-This function should only be called on the cold boot path. It executes with the
-MMU and data caches enabled. The pointer returned by this function must point to
-a ``meminfo`` structure containing the extents and availability of secure RAM for
-the BL1 stage.
-
-::
-
- meminfo.total_base = Base address of secure RAM visible to BL1
- meminfo.total_size = Size of secure RAM visible to BL1
-
-This information is used by BL1 to load the BL2 image in secure RAM. BL1 also
-populates a similar structure to tell BL2 the extents of memory available for
-its own use.
-
-This function helps fulfill requirements 4 and 5 above.
-
-Function : bl1_plat_prepare_exit() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : entry_point_info_t *
- Return : void
-
-This function is called prior to exiting BL1 in response to the
-``BL1_SMC_RUN_IMAGE`` SMC request raised by BL2. It should be used to perform
-platform specific clean up or bookkeeping operations before transferring
-control to the next image. It receives the address of the ``entry_point_info_t``
-structure passed from BL2. This function runs with MMU disabled.
-
-Function : bl1_plat_set_ep_info() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int image_id, entry_point_info_t *ep_info
- Return : void
-
-This function allows platforms to override ``ep_info`` for the given ``image_id``.
-
-The default implementation just returns.
-
-Function : bl1_plat_get_next_image_id() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : unsigned int
-
-This and the following function must be overridden to enable the FWU feature.
-
-BL1 calls this function after platform setup to identify the next image to be
-loaded and executed. If the platform returns ``BL2_IMAGE_ID`` then BL1 proceeds
-with the normal boot sequence, which loads and executes BL2. If the platform
-returns a different image id, BL1 assumes that Firmware Update is required.
-
-The default implementation always returns ``BL2_IMAGE_ID``. The Arm development
-platforms override this function to detect if firmware update is required, and
-if so, return the first image in the firmware update process.
-
-Function : bl1_plat_get_image_desc() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int image_id
- Return : image_desc_t *
-
-BL1 calls this function to get the image descriptor information ``image_desc_t``
-for the provided ``image_id`` from the platform.
-
-The default implementation always returns a common BL2 image descriptor. Arm
-standard platforms return an image descriptor corresponding to BL2 or one of
-the firmware update images defined in the Trusted Board Boot Requirements
-specification.
-
-Function : bl1_plat_handle_pre_image_load() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int image_id
- Return : int
-
-This function can be used by the platforms to update/use image information
-corresponding to ``image_id``. This function is invoked in BL1, both in cold
-boot and FWU code path, before loading the image.
-
-Function : bl1_plat_handle_post_image_load() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int image_id
- Return : int
-
-This function can be used by the platforms to update/use image information
-corresponding to ``image_id``. This function is invoked in BL1, both in cold
-boot and FWU code path, after loading and authenticating the image.
-
-The default weak implementation of this function calculates the amount of
-Trusted SRAM that can be used by BL2 and allocates a ``meminfo_t``
-structure at the beginning of this free memory and populates it. The address
-of ``meminfo_t`` structure is updated in ``arg1`` of the entrypoint
-information to BL2.
-
-Function : bl1_plat_fwu_done() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int image_id, uintptr_t image_src,
- unsigned int image_size
- Return : void
-
-BL1 calls this function when the FWU process is complete. It must not return.
-The platform may override this function to take platform specific action, for
-example to initiate the normal boot flow.
-
-The default implementation spins forever.
-
-Function : bl1_plat_mem_check() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : uintptr_t mem_base, unsigned int mem_size,
- unsigned int flags
- Return : int
-
-BL1 calls this function while handling FWU related SMCs, more specifically when
-copying or authenticating an image. Its responsibility is to ensure that the
-region of memory identified by ``mem_base`` and ``mem_size`` is mapped in BL1, and
-that this memory corresponds to either a secure or non-secure memory region as
-indicated by the security state of the ``flags`` argument.
-
-This function can safely assume that the value resulting from the addition of
-``mem_base`` and ``mem_size`` fits into a ``uintptr_t`` type variable and does not
-overflow.
-
-This function must return 0 on success, a non-null error code otherwise.
-
-The default implementation of this function asserts therefore platforms must
-override it when using the FWU feature.
-
-Boot Loader Stage 2 (BL2)
--------------------------
-
-The BL2 stage is executed only by the primary CPU, which is determined in BL1
-using the ``platform_is_primary_cpu()`` function. BL1 passed control to BL2 at
-``BL2_BASE``. BL2 executes in Secure EL1 and and invokes
-``plat_get_bl_image_load_info()`` to retrieve the list of images to load from
-non-volatile storage to secure/non-secure RAM. After all the images are loaded
-then BL2 invokes ``plat_get_next_bl_params()`` to get the list of executable
-images to be passed to the next BL image.
-
-The following functions must be implemented by the platform port to enable BL2
-to perform the above tasks.
-
-Function : bl2_early_platform_setup2() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : u_register_t, u_register_t, u_register_t, u_register_t
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only called
-by the primary CPU. The 4 arguments are passed by BL1 to BL2 and these arguments
-are platform specific.
-
-On Arm standard platforms, the arguments received are :
-
- arg0 - Points to load address of HW_CONFIG if present
-
- arg1 - ``meminfo`` structure populated by BL1. The platform copies
- the contents of ``meminfo`` as it may be subsequently overwritten by BL2.
-
-On Arm standard platforms, this function also:
-
-- Initializes a UART (PL011 console), which enables access to the ``printf``
- family of functions in BL2.
-
-- Initializes the storage abstraction layer used to load further bootloader
- images. It is necessary to do this early on platforms with a SCP_BL2 image,
- since the later ``bl2_platform_setup`` must be done after SCP_BL2 is loaded.
-
-Function : bl2_plat_arch_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only called
-by the primary CPU.
-
-The purpose of this function is to perform any architectural initialization
-that varies across platforms.
-
-On Arm standard platforms, this function enables the MMU.
-
-Function : bl2_platform_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function may execute with the MMU and data caches enabled if the platform
-port does the necessary initialization in ``bl2_plat_arch_setup()``. It is only
-called by the primary CPU.
-
-The purpose of this function is to perform any platform initialization
-specific to BL2.
-
-In Arm standard platforms, this function performs security setup, including
-configuration of the TrustZone controller to allow non-secure masters access
-to most of DRAM. Part of DRAM is reserved for secure world use.
-
-Function : bl2_plat_handle_pre_image_load() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : int
-
-This function can be used by the platforms to update/use image information
-for given ``image_id``. This function is currently invoked in BL2 before
-loading each image.
-
-Function : bl2_plat_handle_post_image_load() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int
- Return : int
-
-This function can be used by the platforms to update/use image information
-for given ``image_id``. This function is currently invoked in BL2 after
-loading each image.
-
-Function : bl2_plat_preload_setup [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This optional function performs any BL2 platform initialization
-required before image loading, that is not done later in
-bl2_platform_setup(). Specifically, if support for multiple
-boot sources is required, it initializes the boot sequence used by
-plat_try_next_boot_source().
-
-Function : plat_try_next_boot_source() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : int
-
-This optional function passes to the next boot source in the redundancy
-sequence.
-
-This function moves the current boot redundancy source to the next
-element in the boot sequence. If there are no more boot sources then it
-must return 0, otherwise it must return 1. The default implementation
-of this always returns 0.
-
-Boot Loader Stage 2 (BL2) at EL3
---------------------------------
-
-When the platform has a non-TF-A Boot ROM it is desirable to jump
-directly to BL2 instead of TF-A BL1. In this case BL2 is expected to
-execute at EL3 instead of executing at EL1. Refer to the `Firmware
-Design`_ for more information.
-
-All mandatory functions of BL2 must be implemented, except the functions
-bl2_early_platform_setup and bl2_el3_plat_arch_setup, because
-their work is done now by bl2_el3_early_platform_setup and
-bl2_el3_plat_arch_setup. These functions should generally implement
-the bl1_plat_xxx() and bl2_plat_xxx() functionality combined.
-
-
-Function : bl2_el3_early_platform_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : u_register_t, u_register_t, u_register_t, u_register_t
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only called
-by the primary CPU. This function receives four parameters which can be used
-by the platform to pass any needed information from the Boot ROM to BL2.
-
-On Arm standard platforms, this function does the following:
-
-- Initializes a UART (PL011 console), which enables access to the ``printf``
- family of functions in BL2.
-
-- Initializes the storage abstraction layer used to load further bootloader
- images. It is necessary to do this early on platforms with a SCP_BL2 image,
- since the later ``bl2_platform_setup`` must be done after SCP_BL2 is loaded.
-
-- Initializes the private variables that define the memory layout used.
-
-Function : bl2_el3_plat_arch_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only called
-by the primary CPU.
-
-The purpose of this function is to perform any architectural initialization
-that varies across platforms.
-
-On Arm standard platforms, this function enables the MMU.
-
-Function : bl2_el3_plat_prepare_exit() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function is called prior to exiting BL2 and run the next image.
-It should be used to perform platform specific clean up or bookkeeping
-operations before transferring control to the next image. This function
-runs with MMU disabled.
-
-FWU Boot Loader Stage 2 (BL2U)
-------------------------------
-
-The AP Firmware Updater Configuration, BL2U, is an optional part of the FWU
-process and is executed only by the primary CPU. BL1 passes control to BL2U at
-``BL2U_BASE``. BL2U executes in Secure-EL1 and is responsible for:
-
-#. (Optional) Transferring the optional SCP_BL2U binary image from AP secure
- memory to SCP RAM. BL2U uses the SCP_BL2U ``image_info`` passed by BL1.
- ``SCP_BL2U_BASE`` defines the address in AP secure memory where SCP_BL2U
- should be copied from. Subsequent handling of the SCP_BL2U image is
- implemented by the platform specific ``bl2u_plat_handle_scp_bl2u()`` function.
- If ``SCP_BL2U_BASE`` is not defined then this step is not performed.
-
-#. Any platform specific setup required to perform the FWU process. For
- example, Arm standard platforms initialize the TZC controller so that the
- normal world can access DDR memory.
-
-The following functions must be implemented by the platform port to enable
-BL2U to perform the tasks mentioned above.
-
-Function : bl2u_early_platform_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : meminfo *mem_info, void *plat_info
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only
-called by the primary CPU. The arguments to this function is the address
-of the ``meminfo`` structure and platform specific info provided by BL1.
-
-The platform may copy the contents of the ``mem_info`` and ``plat_info`` into
-private storage as the original memory may be subsequently overwritten by BL2U.
-
-On Arm CSS platforms ``plat_info`` is interpreted as an ``image_info_t`` structure,
-to extract SCP_BL2U image information, which is then copied into a private
-variable.
-
-Function : bl2u_plat_arch_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only
-called by the primary CPU.
-
-The purpose of this function is to perform any architectural initialization
-that varies across platforms, for example enabling the MMU (since the memory
-map differs across platforms).
-
-Function : bl2u_platform_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function may execute with the MMU and data caches enabled if the platform
-port does the necessary initialization in ``bl2u_plat_arch_setup()``. It is only
-called by the primary CPU.
-
-The purpose of this function is to perform any platform initialization
-specific to BL2U.
-
-In Arm standard platforms, this function performs security setup, including
-configuration of the TrustZone controller to allow non-secure masters access
-to most of DRAM. Part of DRAM is reserved for secure world use.
-
-Function : bl2u_plat_handle_scp_bl2u() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : int
-
-This function is used to perform any platform-specific actions required to
-handle the SCP firmware. Typically it transfers the image into SCP memory using
-a platform-specific protocol and waits until SCP executes it and signals to the
-Application Processor (AP) for BL2U execution to continue.
-
-This function returns 0 on success, a negative error code otherwise.
-This function is included if SCP_BL2U_BASE is defined.
-
-Boot Loader Stage 3-1 (BL31)
-----------------------------
-
-During cold boot, the BL31 stage is executed only by the primary CPU. This is
-determined in BL1 using the ``platform_is_primary_cpu()`` function. BL1 passes
-control to BL31 at ``BL31_BASE``. During warm boot, BL31 is executed by all
-CPUs. BL31 executes at EL3 and is responsible for:
-
-#. Re-initializing all architectural and platform state. Although BL1 performs
- some of this initialization, BL31 remains resident in EL3 and must ensure
- that EL3 architectural and platform state is completely initialized. It
- should make no assumptions about the system state when it receives control.
-
-#. Passing control to a normal world BL image, pre-loaded at a platform-
- specific address by BL2. On ARM platforms, BL31 uses the ``bl_params`` list
- populated by BL2 in memory to do this.
-
-#. Providing runtime firmware services. Currently, BL31 only implements a
- subset of the Power State Coordination Interface (PSCI) API as a runtime
- service. See Section 3.3 below for details of porting the PSCI
- implementation.
-
-#. Optionally passing control to the BL32 image, pre-loaded at a platform-
- specific address by BL2. BL31 exports a set of APIs that allow runtime
- services to specify the security state in which the next image should be
- executed and run the corresponding image. On ARM platforms, BL31 uses the
- ``bl_params`` list populated by BL2 in memory to do this.
-
-If BL31 is a reset vector, It also needs to handle the reset as specified in
-section 2.2 before the tasks described above.
-
-The following functions must be implemented by the platform port to enable BL31
-to perform the above tasks.
-
-Function : bl31_early_platform_setup2() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : u_register_t, u_register_t, u_register_t, u_register_t
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only called
-by the primary CPU. BL2 can pass 4 arguments to BL31 and these arguments are
-platform specific.
-
-In Arm standard platforms, the arguments received are :
-
- arg0 - The pointer to the head of `bl_params_t` list
- which is list of executable images following BL31,
-
- arg1 - Points to load address of SOC_FW_CONFIG if present
-
- arg2 - Points to load address of HW_CONFIG if present
-
- arg3 - A special value to verify platform parameters from BL2 to BL31. Not
- used in release builds.
-
-The function runs through the `bl_param_t` list and extracts the entry point
-information for BL32 and BL33. It also performs the following:
-
-- Initialize a UART (PL011 console), which enables access to the ``printf``
- family of functions in BL31.
-
-- Enable issuing of snoop and DVM (Distributed Virtual Memory) requests to the
- CCI slave interface corresponding to the cluster that includes the primary
- CPU.
-
-Function : bl31_plat_arch_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function executes with the MMU and data caches disabled. It is only called
-by the primary CPU.
-
-The purpose of this function is to perform any architectural initialization
-that varies across platforms.
-
-On Arm standard platforms, this function enables the MMU.
-
-Function : bl31_platform_setup() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function may execute with the MMU and data caches enabled if the platform
-port does the necessary initialization in ``bl31_plat_arch_setup()``. It is only
-called by the primary CPU.
-
-The purpose of this function is to complete platform initialization so that both
-BL31 runtime services and normal world software can function correctly.
-
-On Arm standard platforms, this function does the following:
-
-- Initialize the generic interrupt controller.
-
- Depending on the GIC driver selected by the platform, the appropriate GICv2
- or GICv3 initialization will be done, which mainly consists of:
-
- - Enable secure interrupts in the GIC CPU interface.
- - Disable the legacy interrupt bypass mechanism.
- - Configure the priority mask register to allow interrupts of all priorities
- to be signaled to the CPU interface.
- - Mark SGIs 8-15 and the other secure interrupts on the platform as secure.
- - Target all secure SPIs to CPU0.
- - Enable these secure interrupts in the GIC distributor.
- - Configure all other interrupts as non-secure.
- - Enable signaling of secure interrupts in the GIC distributor.
-
-- Enable system-level implementation of the generic timer counter through the
- memory mapped interface.
-
-- Grant access to the system counter timer module
-
-- Initialize the power controller device.
-
- In particular, initialise the locks that prevent concurrent accesses to the
- power controller device.
-
-Function : bl31_plat_runtime_setup() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-The purpose of this function is allow the platform to perform any BL31 runtime
-setup just prior to BL31 exit during cold boot. The default weak
-implementation of this function will invoke ``console_switch_state()`` to switch
-console output to consoles marked for use in the ``runtime`` state.
-
-Function : bl31_plat_get_next_image_ep_info() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : uint32_t
- Return : entry_point_info *
-
-This function may execute with the MMU and data caches enabled if the platform
-port does the necessary initializations in ``bl31_plat_arch_setup()``.
-
-This function is called by ``bl31_main()`` to retrieve information provided by
-BL2 for the next image in the security state specified by the argument. BL31
-uses this information to pass control to that image in the specified security
-state. This function must return a pointer to the ``entry_point_info`` structure
-(that was copied during ``bl31_early_platform_setup()``) if the image exists. It
-should return NULL otherwise.
-
-Function : bl31_plat_enable_mmu [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : uint32_t
- Return : void
-
-This function enables the MMU. The boot code calls this function with MMU and
-caches disabled. This function should program necessary registers to enable
-translation, and upon return, the MMU on the calling PE must be enabled.
-
-The function must honor flags passed in the first argument. These flags are
-defined by the translation library, and can be found in the file
-``include/lib/xlat_tables/xlat_mmu_helpers.h``.
-
-On DynamIQ systems, this function must not use stack while enabling MMU, which
-is how the function in xlat table library version 2 is implemented.
-
-Function : plat_init_apiakey [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : uint64_t *
-
-This function populates the ``plat_apiakey`` array that contains the values used
-to set the ``APIAKey{Hi,Lo}_EL1`` registers. It returns a pointer to this array.
-
-The value should be obtained from a reliable source of randomness.
-
-This function is only needed if ARMv8.3 pointer authentication is used in the
-Trusted Firmware by building with ``ENABLE_PAUTH=1``.
-
-Function : plat_get_syscnt_freq2() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : unsigned int
-
-This function is used by the architecture setup code to retrieve the counter
-frequency for the CPU's generic timer. This value will be programmed into the
-``CNTFRQ_EL0`` register. In Arm standard platforms, it returns the base frequency
-of the system counter, which is retrieved from the first entry in the frequency
-modes table.
-
-#define : PLAT_PERCPU_BAKERY_LOCK_SIZE [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When ``USE_COHERENT_MEM = 0``, this constant defines the total memory (in
-bytes) aligned to the cache line boundary that should be allocated per-cpu to
-accommodate all the bakery locks.
-
-If this constant is not defined when ``USE_COHERENT_MEM = 0``, the linker
-calculates the size of the ``bakery_lock`` input section, aligns it to the
-nearest ``CACHE_WRITEBACK_GRANULE``, multiplies it with ``PLATFORM_CORE_COUNT``
-and stores the result in a linker symbol. This constant prevents a platform
-from relying on the linker and provide a more efficient mechanism for
-accessing per-cpu bakery lock information.
-
-If this constant is defined and its value is not equal to the value
-calculated by the linker then a link time assertion is raised. A compile time
-assertion is raised if the value of the constant is not aligned to the cache
-line boundary.
-
-SDEI porting requirements
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The SDEI dispatcher requires the platform to provide the following macros
-and functions, of which some are optional, and some others mandatory.
-
-Macros
-......
-
-Macro: PLAT_SDEI_NORMAL_PRI [mandatory]
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This macro must be defined to the EL3 exception priority level associated with
-Normal SDEI events on the platform. This must have a higher value (therefore of
-lower priority) than ``PLAT_SDEI_CRITICAL_PRI``.
-
-Macro: PLAT_SDEI_CRITICAL_PRI [mandatory]
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This macro must be defined to the EL3 exception priority level associated with
-Critical SDEI events on the platform. This must have a lower value (therefore of
-higher priority) than ``PLAT_SDEI_NORMAL_PRI``.
-
-**Note**: SDEI exception priorities must be the lowest among Secure priorities.
-Among the SDEI exceptions, Critical SDEI priority must be higher than Normal
-SDEI priority.
-
-Functions
-.........
-
-Function: int plat_sdei_validate_entry_point(uintptr_t ep) [optional]
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
- Argument: uintptr_t
- Return: int
-
-This function validates the address of client entry points provided for both
-event registration and *Complete and Resume* SDEI calls. The function takes one
-argument, which is the address of the handler the SDEI client requested to
-register. The function must return ``0`` for successful validation, or ``-1``
-upon failure.
-
-The default implementation always returns ``0``. On Arm platforms, this function
-is implemented to translate the entry point to physical address, and further to
-ensure that the address is located in Non-secure DRAM.
-
-Function: void plat_sdei_handle_masked_trigger(uint64_t mpidr, unsigned int intr) [optional]
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-::
-
- Argument: uint64_t
- Argument: unsigned int
- Return: void
-
-SDEI specification requires that a PE comes out of reset with the events masked.
-The client therefore is expected to call ``PE_UNMASK`` to unmask SDEI events on
-the PE. No SDEI events can be dispatched until such time.
-
-Should a PE receive an interrupt that was bound to an SDEI event while the
-events are masked on the PE, the dispatcher implementation invokes the function
-``plat_sdei_handle_masked_trigger``. The MPIDR of the PE that received the
-interrupt and the interrupt ID are passed as parameters.
-
-The default implementation only prints out a warning message.
-
-Power State Coordination Interface (in BL31)
---------------------------------------------
-
-The TF-A implementation of the PSCI API is based around the concept of a
-*power domain*. A *power domain* is a CPU or a logical group of CPUs which
-share some state on which power management operations can be performed as
-specified by `PSCI`_. Each CPU in the system is assigned a cpu index which is
-a unique number between ``0`` and ``PLATFORM_CORE_COUNT - 1``. The
-*power domains* are arranged in a hierarchical tree structure and each
-*power domain* can be identified in a system by the cpu index of any CPU that
-is part of that domain and a *power domain level*. A processing element (for
-example, a CPU) is at level 0. If the *power domain* node above a CPU is a
-logical grouping of CPUs that share some state, then level 1 is that group of
-CPUs (for example, a cluster), and level 2 is a group of clusters (for
-example, the system). More details on the power domain topology and its
-organization can be found in `Power Domain Topology Design`_.
-
-BL31's platform initialization code exports a pointer to the platform-specific
-power management operations required for the PSCI implementation to function
-correctly. This information is populated in the ``plat_psci_ops`` structure. The
-PSCI implementation calls members of the ``plat_psci_ops`` structure for performing
-power management operations on the power domains. For example, the target
-CPU is specified by its ``MPIDR`` in a PSCI ``CPU_ON`` call. The ``pwr_domain_on()``
-handler (if present) is called for the CPU power domain.
-
-The ``power-state`` parameter of a PSCI ``CPU_SUSPEND`` call can be used to
-describe composite power states specific to a platform. The PSCI implementation
-defines a generic representation of the power-state parameter, which is an
-array of local power states where each index corresponds to a power domain
-level. Each entry contains the local power state the power domain at that power
-level could enter. It depends on the ``validate_power_state()`` handler to
-convert the power-state parameter (possibly encoding a composite power state)
-passed in a PSCI ``CPU_SUSPEND`` call to this representation.
-
-The following functions form part of platform port of PSCI functionality.
-
-Function : plat_psci_stat_accounting_start() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : const psci_power_state_t *
- Return : void
-
-This is an optional hook that platforms can implement for residency statistics
-accounting before entering a low power state. The ``pwr_domain_state`` field of
-``state_info`` (first argument) can be inspected if stat accounting is done
-differently at CPU level versus higher levels. As an example, if the element at
-index 0 (CPU power level) in the ``pwr_domain_state`` array indicates a power down
-state, special hardware logic may be programmed in order to keep track of the
-residency statistics. For higher levels (array indices > 0), the residency
-statistics could be tracked in software using PMF. If ``ENABLE_PMF`` is set, the
-default implementation will use PMF to capture timestamps.
-
-Function : plat_psci_stat_accounting_stop() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : const psci_power_state_t *
- Return : void
-
-This is an optional hook that platforms can implement for residency statistics
-accounting after exiting from a low power state. The ``pwr_domain_state`` field
-of ``state_info`` (first argument) can be inspected if stat accounting is done
-differently at CPU level versus higher levels. As an example, if the element at
-index 0 (CPU power level) in the ``pwr_domain_state`` array indicates a power down
-state, special hardware logic may be programmed in order to keep track of the
-residency statistics. For higher levels (array indices > 0), the residency
-statistics could be tracked in software using PMF. If ``ENABLE_PMF`` is set, the
-default implementation will use PMF to capture timestamps.
-
-Function : plat_psci_stat_get_residency() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int, const psci_power_state_t *, int
- Return : u_register_t
-
-This is an optional interface that is is invoked after resuming from a low power
-state and provides the time spent resident in that low power state by the power
-domain at a particular power domain level. When a CPU wakes up from suspend,
-all its parent power domain levels are also woken up. The generic PSCI code
-invokes this function for each parent power domain that is resumed and it
-identified by the ``lvl`` (first argument) parameter. The ``state_info`` (second
-argument) describes the low power state that the power domain has resumed from.
-The current CPU is the first CPU in the power domain to resume from the low
-power state and the ``last_cpu_idx`` (third parameter) is the index of the last
-CPU in the power domain to suspend and may be needed to calculate the residency
-for that power domain.
-
-Function : plat_get_target_pwr_state() [optional]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : unsigned int, const plat_local_state_t *, unsigned int
- Return : plat_local_state_t
-
-The PSCI generic code uses this function to let the platform participate in
-state coordination during a power management operation. The function is passed
-a pointer to an array of platform specific local power state ``states`` (second
-argument) which contains the requested power state for each CPU at a particular
-power domain level ``lvl`` (first argument) within the power domain. The function
-is expected to traverse this array of upto ``ncpus`` (third argument) and return
-a coordinated target power state by the comparing all the requested power
-states. The target power state should not be deeper than any of the requested
-power states.
-
-A weak definition of this API is provided by default wherein it assumes
-that the platform assigns a local state value in order of increasing depth
-of the power state i.e. for two power states X & Y, if X < Y
-then X represents a shallower power state than Y. As a result, the
-coordinated target local power state for a power domain will be the minimum
-of the requested local power state values.
-
-Function : plat_get_power_domain_tree_desc() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : const unsigned char *
-
-This function returns a pointer to the byte array containing the power domain
-topology tree description. The format and method to construct this array are
-described in `Power Domain Topology Design`_. The BL31 PSCI initialization code
-requires this array to be described by the platform, either statically or
-dynamically, to initialize the power domain topology tree. In case the array
-is populated dynamically, then plat_core_pos_by_mpidr() and
-plat_my_core_pos() should also be implemented suitably so that the topology
-tree description matches the CPU indices returned by these APIs. These APIs
-together form the platform interface for the PSCI topology framework.
-
-Function : plat_setup_psci_ops() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : uintptr_t, const plat_psci_ops **
- Return : int
-
-This function may execute with the MMU and data caches enabled if the platform
-port does the necessary initializations in ``bl31_plat_arch_setup()``. It is only
-called by the primary CPU.
-
-This function is called by PSCI initialization code. Its purpose is to let
-the platform layer know about the warm boot entrypoint through the
-``sec_entrypoint`` (first argument) and to export handler routines for
-platform-specific psci power management actions by populating the passed
-pointer with a pointer to BL31's private ``plat_psci_ops`` structure.
-
-A description of each member of this structure is given below. Please refer to
-the Arm FVP specific implementation of these handlers in
-`plat/arm/board/fvp/fvp_pm.c`_ as an example. For each PSCI function that the
-platform wants to support, the associated operation or operations in this
-structure must be provided and implemented (Refer section 4 of
-`Firmware Design`_ for the PSCI API supported in TF-A). To disable a PSCI
-function in a platform port, the operation should be removed from this
-structure instead of providing an empty implementation.
-
-plat_psci_ops.cpu_standby()
-...........................
-
-Perform the platform-specific actions to enter the standby state for a cpu
-indicated by the passed argument. This provides a fast path for CPU standby
-wherein overheads of PSCI state management and lock acquisition is avoided.
-For this handler to be invoked by the PSCI ``CPU_SUSPEND`` API implementation,
-the suspend state type specified in the ``power-state`` parameter should be
-STANDBY and the target power domain level specified should be the CPU. The
-handler should put the CPU into a low power retention state (usually by
-issuing a wfi instruction) and ensure that it can be woken up from that
-state by a normal interrupt. The generic code expects the handler to succeed.
-
-plat_psci_ops.pwr_domain_on()
-.............................
-
-Perform the platform specific actions to power on a CPU, specified
-by the ``MPIDR`` (first argument). The generic code expects the platform to
-return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure.
-
-plat_psci_ops.pwr_domain_off()
-..............................
-
-Perform the platform specific actions to prepare to power off the calling CPU
-and its higher parent power domain levels as indicated by the ``target_state``
-(first argument). It is called by the PSCI ``CPU_OFF`` API implementation.
-
-The ``target_state`` encodes the platform coordinated target local power states
-for the CPU power domain and its parent power domain levels. The handler
-needs to perform power management operation corresponding to the local state
-at each power level.
-
-For this handler, the local power state for the CPU power domain will be a
-power down state where as it could be either power down, retention or run state
-for the higher power domain levels depending on the result of state
-coordination. The generic code expects the handler to succeed.
-
-plat_psci_ops.pwr_domain_suspend_pwrdown_early() [optional]
-...........................................................
-
-This optional function may be used as a performance optimization to replace
-or complement pwr_domain_suspend() on some platforms. Its calling semantics
-are identical to pwr_domain_suspend(), except the PSCI implementation only
-calls this function when suspending to a power down state, and it guarantees
-that data caches are enabled.
-
-When HW_ASSISTED_COHERENCY = 0, the PSCI implementation disables data caches
-before calling pwr_domain_suspend(). If the target_state corresponds to a
-power down state and it is safe to perform some or all of the platform
-specific actions in that function with data caches enabled, it may be more
-efficient to move those actions to this function. When HW_ASSISTED_COHERENCY
-= 1, data caches remain enabled throughout, and so there is no advantage to
-moving platform specific actions to this function.
-
-plat_psci_ops.pwr_domain_suspend()
-..................................
-
-Perform the platform specific actions to prepare to suspend the calling
-CPU and its higher parent power domain levels as indicated by the
-``target_state`` (first argument). It is called by the PSCI ``CPU_SUSPEND``
-API implementation.
-
-The ``target_state`` has a similar meaning as described in
-the ``pwr_domain_off()`` operation. It encodes the platform coordinated
-target local power states for the CPU power domain and its parent
-power domain levels. The handler needs to perform power management operation
-corresponding to the local state at each power level. The generic code
-expects the handler to succeed.
-
-The difference between turning a power domain off versus suspending it is that
-in the former case, the power domain is expected to re-initialize its state
-when it is next powered on (see ``pwr_domain_on_finish()``). In the latter
-case, the power domain is expected to save enough state so that it can resume
-execution by restoring this state when its powered on (see
-``pwr_domain_suspend_finish()``).
-
-When suspending a core, the platform can also choose to power off the GICv3
-Redistributor and ITS through an implementation-defined sequence. To achieve
-this safely, the ITS context must be saved first. The architectural part is
-implemented by the ``gicv3_its_save_disable()`` helper, but most of the needed
-sequence is implementation defined and it is therefore the responsibility of
-the platform code to implement the necessary sequence. Then the GIC
-Redistributor context can be saved using the ``gicv3_rdistif_save()`` helper.
-Powering off the Redistributor requires the implementation to support it and it
-is the responsibility of the platform code to execute the right implementation
-defined sequence.
-
-When a system suspend is requested, the platform can also make use of the
-``gicv3_distif_save()`` helper to save the context of the GIC Distributor after
-it has saved the context of the Redistributors and ITS of all the cores in the
-system. The context of the Distributor can be large and may require it to be
-allocated in a special area if it cannot fit in the platform's global static
-data, for example in DRAM. The Distributor can then be powered down using an
-implementation-defined sequence.
-
-plat_psci_ops.pwr_domain_pwr_down_wfi()
-.......................................
-
-This is an optional function and, if implemented, is expected to perform
-platform specific actions including the ``wfi`` invocation which allows the
-CPU to powerdown. Since this function is invoked outside the PSCI locks,
-the actions performed in this hook must be local to the CPU or the platform
-must ensure that races between multiple CPUs cannot occur.
-
-The ``target_state`` has a similar meaning as described in the ``pwr_domain_off()``
-operation and it encodes the platform coordinated target local power states for
-the CPU power domain and its parent power domain levels. This function must
-not return back to the caller.
-
-If this function is not implemented by the platform, PSCI generic
-implementation invokes ``psci_power_down_wfi()`` for power down.
-
-plat_psci_ops.pwr_domain_on_finish()
-....................................
-
-This function is called by the PSCI implementation after the calling CPU is
-powered on and released from reset in response to an earlier PSCI ``CPU_ON`` call.
-It performs the platform-specific setup required to initialize enough state for
-this CPU to enter the normal world and also provide secure runtime firmware
-services.
-
-The ``target_state`` (first argument) is the prior state of the power domains
-immediately before the CPU was turned on. It indicates which power domains
-above the CPU might require initialization due to having previously been in
-low power states. The generic code expects the handler to succeed.
-
-plat_psci_ops.pwr_domain_suspend_finish()
-.........................................
-
-This function is called by the PSCI implementation after the calling CPU is
-powered on and released from reset in response to an asynchronous wakeup
-event, for example a timer interrupt that was programmed by the CPU during the
-``CPU_SUSPEND`` call or ``SYSTEM_SUSPEND`` call. It performs the platform-specific
-setup required to restore the saved state for this CPU to resume execution
-in the normal world and also provide secure runtime firmware services.
-
-The ``target_state`` (first argument) has a similar meaning as described in
-the ``pwr_domain_on_finish()`` operation. The generic code expects the platform
-to succeed.
-
-If the Distributor, Redistributors or ITS have been powered off as part of a
-suspend, their context must be restored in this function in the reverse order
-to how they were saved during suspend sequence.
-
-plat_psci_ops.system_off()
-..........................
-
-This function is called by PSCI implementation in response to a ``SYSTEM_OFF``
-call. It performs the platform-specific system poweroff sequence after
-notifying the Secure Payload Dispatcher.
-
-plat_psci_ops.system_reset()
-............................
-
-This function is called by PSCI implementation in response to a ``SYSTEM_RESET``
-call. It performs the platform-specific system reset sequence after
-notifying the Secure Payload Dispatcher.
-
-plat_psci_ops.validate_power_state()
-....................................
-
-This function is called by the PSCI implementation during the ``CPU_SUSPEND``
-call to validate the ``power_state`` parameter of the PSCI API and if valid,
-populate it in ``req_state`` (second argument) array as power domain level
-specific local states. If the ``power_state`` is invalid, the platform must
-return PSCI_E_INVALID_PARAMS as error, which is propagated back to the
-normal world PSCI client.
-
-plat_psci_ops.validate_ns_entrypoint()
-......................................
-
-This function is called by the PSCI implementation during the ``CPU_SUSPEND``,
-``SYSTEM_SUSPEND`` and ``CPU_ON`` calls to validate the non-secure ``entry_point``
-parameter passed by the normal world. If the ``entry_point`` is invalid,
-the platform must return PSCI_E_INVALID_ADDRESS as error, which is
-propagated back to the normal world PSCI client.
-
-plat_psci_ops.get_sys_suspend_power_state()
-...........................................
-
-This function is called by the PSCI implementation during the ``SYSTEM_SUSPEND``
-call to get the ``req_state`` parameter from platform which encodes the power
-domain level specific local states to suspend to system affinity level. The
-``req_state`` will be utilized to do the PSCI state coordination and
-``pwr_domain_suspend()`` will be invoked with the coordinated target state to
-enter system suspend.
-
-plat_psci_ops.get_pwr_lvl_state_idx()
-.....................................
-
-This is an optional function and, if implemented, is invoked by the PSCI
-implementation to convert the ``local_state`` (first argument) at a specified
-``pwr_lvl`` (second argument) to an index between 0 and
-``PLAT_MAX_PWR_LVL_STATES`` - 1. This function is only needed if the platform
-supports more than two local power states at each power domain level, that is
-``PLAT_MAX_PWR_LVL_STATES`` is greater than 2, and needs to account for these
-local power states.
-
-plat_psci_ops.translate_power_state_by_mpidr()
-..............................................
-
-This is an optional function and, if implemented, verifies the ``power_state``
-(second argument) parameter of the PSCI API corresponding to a target power
-domain. The target power domain is identified by using both ``MPIDR`` (first
-argument) and the power domain level encoded in ``power_state``. The power domain
-level specific local states are to be extracted from ``power_state`` and be
-populated in the ``output_state`` (third argument) array. The functionality
-is similar to the ``validate_power_state`` function described above and is
-envisaged to be used in case the validity of ``power_state`` depend on the
-targeted power domain. If the ``power_state`` is invalid for the targeted power
-domain, the platform must return PSCI_E_INVALID_PARAMS as error. If this
-function is not implemented, then the generic implementation relies on
-``validate_power_state`` function to translate the ``power_state``.
-
-This function can also be used in case the platform wants to support local
-power state encoding for ``power_state`` parameter of PSCI_STAT_COUNT/RESIDENCY
-APIs as described in Section 5.18 of `PSCI`_.
-
-plat_psci_ops.get_node_hw_state()
-.................................
-
-This is an optional function. If implemented this function is intended to return
-the power state of a node (identified by the first parameter, the ``MPIDR``) in
-the power domain topology (identified by the second parameter, ``power_level``),
-as retrieved from a power controller or equivalent component on the platform.
-Upon successful completion, the implementation must map and return the final
-status among ``HW_ON``, ``HW_OFF`` or ``HW_STANDBY``. Upon encountering failures, it
-must return either ``PSCI_E_INVALID_PARAMS`` or ``PSCI_E_NOT_SUPPORTED`` as
-appropriate.
-
-Implementations are not expected to handle ``power_levels`` greater than
-``PLAT_MAX_PWR_LVL``.
-
-plat_psci_ops.system_reset2()
-.............................
-
-This is an optional function. If implemented this function is
-called during the ``SYSTEM_RESET2`` call to perform a reset
-based on the first parameter ``reset_type`` as specified in
-`PSCI`_. The parameter ``cookie`` can be used to pass additional
-reset information. If the ``reset_type`` is not supported, the
-function must return ``PSCI_E_NOT_SUPPORTED``. For architectural
-resets, all failures must return ``PSCI_E_INVALID_PARAMETERS``
-and vendor reset can return other PSCI error codes as defined
-in `PSCI`_. On success this function will not return.
-
-plat_psci_ops.write_mem_protect()
-.................................
-
-This is an optional function. If implemented it enables or disables the
-``MEM_PROTECT`` functionality based on the value of ``val``.
-A non-zero value enables ``MEM_PROTECT`` and a value of zero
-disables it. Upon encountering failures it must return a negative value
-and on success it must return 0.
-
-plat_psci_ops.read_mem_protect()
-................................
-
-This is an optional function. If implemented it returns the current
-state of ``MEM_PROTECT`` via the ``val`` parameter. Upon encountering
-failures it must return a negative value and on success it must
-return 0.
-
-plat_psci_ops.mem_protect_chk()
-...............................
-
-This is an optional function. If implemented it checks if a memory
-region defined by a base address ``base`` and with a size of ``length``
-bytes is protected by ``MEM_PROTECT``. If the region is protected
-then it must return 0, otherwise it must return a negative number.
-
-Interrupt Management framework (in BL31)
-----------------------------------------
-
-BL31 implements an Interrupt Management Framework (IMF) to manage interrupts
-generated in either security state and targeted to EL1 or EL2 in the non-secure
-state or EL3/S-EL1 in the secure state. The design of this framework is
-described in the `IMF Design Guide`_
-
-A platform should export the following APIs to support the IMF. The following
-text briefly describes each API and its implementation in Arm standard
-platforms. The API implementation depends upon the type of interrupt controller
-present in the platform. Arm standard platform layer supports both
-`Arm Generic Interrupt Controller version 2.0 (GICv2)`_
-and `3.0 (GICv3)`_. Juno builds the Arm platform layer to use GICv2 and the
-FVP can be configured to use either GICv2 or GICv3 depending on the build flag
-``FVP_USE_GIC_DRIVER`` (See FVP platform specific build options in
-`User Guide`_ for more details).
-
-See also: `Interrupt Controller Abstraction APIs`__.
-
-.. __: platform-interrupt-controller-API.rst
-
-Function : plat_interrupt_type_to_line() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : uint32_t, uint32_t
- Return : uint32_t
-
-The Arm processor signals an interrupt exception either through the IRQ or FIQ
-interrupt line. The specific line that is signaled depends on how the interrupt
-controller (IC) reports different interrupt types from an execution context in
-either security state. The IMF uses this API to determine which interrupt line
-the platform IC uses to signal each type of interrupt supported by the framework
-from a given security state. This API must be invoked at EL3.
-
-The first parameter will be one of the ``INTR_TYPE_*`` values (see
-`IMF Design Guide`_) indicating the target type of the interrupt, the second parameter is the
-security state of the originating execution context. The return result is the
-bit position in the ``SCR_EL3`` register of the respective interrupt trap: IRQ=1,
-FIQ=2.
-
-In the case of Arm standard platforms using GICv2, S-EL1 interrupts are
-configured as FIQs and Non-secure interrupts as IRQs from either security
-state.
-
-In the case of Arm standard platforms using GICv3, the interrupt line to be
-configured depends on the security state of the execution context when the
-interrupt is signalled and are as follows:
-
-- The S-EL1 interrupts are signaled as IRQ in S-EL0/1 context and as FIQ in
- NS-EL0/1/2 context.
-- The Non secure interrupts are signaled as FIQ in S-EL0/1 context and as IRQ
- in the NS-EL0/1/2 context.
-- The EL3 interrupts are signaled as FIQ in both S-EL0/1 and NS-EL0/1/2
- context.
-
-Function : plat_ic_get_pending_interrupt_type() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : uint32_t
-
-This API returns the type of the highest priority pending interrupt at the
-platform IC. The IMF uses the interrupt type to retrieve the corresponding
-handler function. ``INTR_TYPE_INVAL`` is returned when there is no interrupt
-pending. The valid interrupt types that can be returned are ``INTR_TYPE_EL3``,
-``INTR_TYPE_S_EL1`` and ``INTR_TYPE_NS``. This API must be invoked at EL3.
-
-In the case of Arm standard platforms using GICv2, the *Highest Priority
-Pending Interrupt Register* (``GICC_HPPIR``) is read to determine the id of
-the pending interrupt. The type of interrupt depends upon the id value as
-follows.
-
-#. id < 1022 is reported as a S-EL1 interrupt
-#. id = 1022 is reported as a Non-secure interrupt.
-#. id = 1023 is reported as an invalid interrupt type.
-
-In the case of Arm standard platforms using GICv3, the system register
-``ICC_HPPIR0_EL1``, *Highest Priority Pending group 0 Interrupt Register*,
-is read to determine the id of the pending interrupt. The type of interrupt
-depends upon the id value as follows.
-
-#. id = ``PENDING_G1S_INTID`` (1020) is reported as a S-EL1 interrupt
-#. id = ``PENDING_G1NS_INTID`` (1021) is reported as a Non-secure interrupt.
-#. id = ``GIC_SPURIOUS_INTERRUPT`` (1023) is reported as an invalid interrupt type.
-#. All other interrupt id's are reported as EL3 interrupt.
-
-Function : plat_ic_get_pending_interrupt_id() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : uint32_t
-
-This API returns the id of the highest priority pending interrupt at the
-platform IC. ``INTR_ID_UNAVAILABLE`` is returned when there is no interrupt
-pending.
-
-In the case of Arm standard platforms using GICv2, the *Highest Priority
-Pending Interrupt Register* (``GICC_HPPIR``) is read to determine the id of the
-pending interrupt. The id that is returned by API depends upon the value of
-the id read from the interrupt controller as follows.
-
-#. id < 1022. id is returned as is.
-#. id = 1022. The *Aliased Highest Priority Pending Interrupt Register*
- (``GICC_AHPPIR``) is read to determine the id of the non-secure interrupt.
- This id is returned by the API.
-#. id = 1023. ``INTR_ID_UNAVAILABLE`` is returned.
-
-In the case of Arm standard platforms using GICv3, if the API is invoked from
-EL3, the system register ``ICC_HPPIR0_EL1``, *Highest Priority Pending Interrupt
-group 0 Register*, is read to determine the id of the pending interrupt. The id
-that is returned by API depends upon the value of the id read from the
-interrupt controller as follows.
-
-#. id < ``PENDING_G1S_INTID`` (1020). id is returned as is.
-#. id = ``PENDING_G1S_INTID`` (1020) or ``PENDING_G1NS_INTID`` (1021). The system
- register ``ICC_HPPIR1_EL1``, *Highest Priority Pending Interrupt group 1
- Register* is read to determine the id of the group 1 interrupt. This id
- is returned by the API as long as it is a valid interrupt id
-#. If the id is any of the special interrupt identifiers,
- ``INTR_ID_UNAVAILABLE`` is returned.
-
-When the API invoked from S-EL1 for GICv3 systems, the id read from system
-register ``ICC_HPPIR1_EL1``, *Highest Priority Pending group 1 Interrupt
-Register*, is returned if is not equal to GIC_SPURIOUS_INTERRUPT (1023) else
-``INTR_ID_UNAVAILABLE`` is returned.
-
-Function : plat_ic_acknowledge_interrupt() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : uint32_t
-
-This API is used by the CPU to indicate to the platform IC that processing of
-the highest pending interrupt has begun. It should return the raw, unmodified
-value obtained from the interrupt controller when acknowledging an interrupt.
-The actual interrupt number shall be extracted from this raw value using the API
-`plat_ic_get_interrupt_id()`__.
-
-.. __: platform-interrupt-controller-API.rst#function-unsigned-int-plat-ic-get-interrupt-id-unsigned-int-raw-optional
-
-This function in Arm standard platforms using GICv2, reads the *Interrupt
-Acknowledge Register* (``GICC_IAR``). This changes the state of the highest
-priority pending interrupt from pending to active in the interrupt controller.
-It returns the value read from the ``GICC_IAR``, unmodified.
-
-In the case of Arm standard platforms using GICv3, if the API is invoked
-from EL3, the function reads the system register ``ICC_IAR0_EL1``, *Interrupt
-Acknowledge Register group 0*. If the API is invoked from S-EL1, the function
-reads the system register ``ICC_IAR1_EL1``, *Interrupt Acknowledge Register
-group 1*. The read changes the state of the highest pending interrupt from
-pending to active in the interrupt controller. The value read is returned
-unmodified.
-
-The TSP uses this API to start processing of the secure physical timer
-interrupt.
-
-Function : plat_ic_end_of_interrupt() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : uint32_t
- Return : void
-
-This API is used by the CPU to indicate to the platform IC that processing of
-the interrupt corresponding to the id (passed as the parameter) has
-finished. The id should be the same as the id returned by the
-``plat_ic_acknowledge_interrupt()`` API.
-
-Arm standard platforms write the id to the *End of Interrupt Register*
-(``GICC_EOIR``) in case of GICv2, and to ``ICC_EOIR0_EL1`` or ``ICC_EOIR1_EL1``
-system register in case of GICv3 depending on where the API is invoked from,
-EL3 or S-EL1. This deactivates the corresponding interrupt in the interrupt
-controller.
-
-The TSP uses this API to finish processing of the secure physical timer
-interrupt.
-
-Function : plat_ic_get_interrupt_type() [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : uint32_t
- Return : uint32_t
-
-This API returns the type of the interrupt id passed as the parameter.
-``INTR_TYPE_INVAL`` is returned if the id is invalid. If the id is valid, a valid
-interrupt type (one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1`` and ``INTR_TYPE_NS``) is
-returned depending upon how the interrupt has been configured by the platform
-IC. This API must be invoked at EL3.
-
-Arm standard platforms using GICv2 configures S-EL1 interrupts as Group0 interrupts
-and Non-secure interrupts as Group1 interrupts. It reads the group value
-corresponding to the interrupt id from the relevant *Interrupt Group Register*
-(``GICD_IGROUPRn``). It uses the group value to determine the type of interrupt.
-
-In the case of Arm standard platforms using GICv3, both the *Interrupt Group
-Register* (``GICD_IGROUPRn``) and *Interrupt Group Modifier Register*
-(``GICD_IGRPMODRn``) is read to figure out whether the interrupt is configured
-as Group 0 secure interrupt, Group 1 secure interrupt or Group 1 NS interrupt.
-
-Crash Reporting mechanism (in BL31)
------------------------------------
-
-BL31 implements a crash reporting mechanism which prints the various registers
-of the CPU to enable quick crash analysis and debugging. This mechanism relies
-on the platform implementing ``plat_crash_console_init``,
-``plat_crash_console_putc`` and ``plat_crash_console_flush``.
-
-The file ``plat/common/aarch64/crash_console_helpers.S`` contains sample
-implementation of all of them. Platforms may include this file to their
-makefiles in order to benefit from them. By default, they will cause the crash
-output to be routed over the normal console infrastructure and get printed on
-consoles configured to output in crash state. ``console_set_scope()`` can be
-used to control whether a console is used for crash output.
-NOTE: Platforms are responsible for making sure that they only mark consoles for
-use in the crash scope that are able to support this, i.e. that are written in
-assembly and conform with the register clobber rules for putc() (x0-x2, x16-x17)
-and flush() (x0-x3, x16-x17) crash callbacks.
-
-In some cases (such as debugging very early crashes that happen before the
-normal boot console can be set up), platforms may want to control crash output
-more explicitly. These platforms may instead provide custom implementations for
-these. They are executed outside of a C environment and without a stack. Many
-console drivers provide functions named ``console_xxx_core_init/putc/flush``
-that are designed to be used by these functions. See Arm platforms (like juno)
-for an example of this.
-
-Function : plat_crash_console_init [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : int
-
-This API is used by the crash reporting mechanism to initialize the crash
-console. It must only use the general purpose registers x0 through x7 to do the
-initialization and returns 1 on success.
-
-Function : plat_crash_console_putc [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : int
- Return : int
-
-This API is used by the crash reporting mechanism to print a character on the
-designated crash console. It must only use general purpose registers x1 and
-x2 to do its work. The parameter and the return value are in general purpose
-register x0.
-
-Function : plat_crash_console_flush [mandatory]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : int
-
-This API is used by the crash reporting mechanism to force write of all buffered
-data on the designated crash console. It should only use general purpose
-registers x0 through x5 to do its work. The return value is 0 on successful
-completion; otherwise the return value is -1.
-
-External Abort handling and RAS Support
----------------------------------------
-
-Function : plat_ea_handler
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : int
- Argument : uint64_t
- Argument : void *
- Argument : void *
- Argument : uint64_t
- Return : void
-
-This function is invoked by the RAS framework for the platform to handle an
-External Abort received at EL3. The intention of the function is to attempt to
-resolve the cause of External Abort and return; if that's not possible, to
-initiate orderly shutdown of the system.
-
-The first parameter (``int ea_reason``) indicates the reason for External Abort.
-Its value is one of ``ERROR_EA_*`` constants defined in ``ea_handle.h``.
-
-The second parameter (``uint64_t syndrome``) is the respective syndrome
-presented to EL3 after having received the External Abort. Depending on the
-nature of the abort (as can be inferred from the ``ea_reason`` parameter), this
-can be the content of either ``ESR_EL3`` or ``DISR_EL1``.
-
-The third parameter (``void *cookie``) is unused for now. The fourth parameter
-(``void *handle``) is a pointer to the preempted context. The fifth parameter
-(``uint64_t flags``) indicates the preempted security state. These parameters
-are received from the top-level exception handler.
-
-If ``RAS_EXTENSION`` is set to ``1``, the default implementation of this
-function iterates through RAS handlers registered by the platform. If any of the
-RAS handlers resolve the External Abort, no further action is taken.
-
-If ``RAS_EXTENSION`` is set to ``0``, or if none of the platform RAS handlers
-could resolve the External Abort, the default implementation prints an error
-message, and panics.
-
-Function : plat_handle_uncontainable_ea
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : int
- Argument : uint64_t
- Return : void
-
-This function is invoked by the RAS framework when an External Abort of
-Uncontainable type is received at EL3. Due to the critical nature of
-Uncontainable errors, the intention of this function is to initiate orderly
-shutdown of the system, and is not expected to return.
-
-This function must be implemented in assembly.
-
-The first and second parameters are the same as that of ``plat_ea_handler``.
-
-The default implementation of this function calls
-``report_unhandled_exception``.
-
-Function : plat_handle_double_fault
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : int
- Argument : uint64_t
- Return : void
-
-This function is invoked by the RAS framework when another External Abort is
-received at EL3 while one is already being handled. I.e., a call to
-``plat_ea_handler`` is outstanding. Due to its critical nature, the intention of
-this function is to initiate orderly shutdown of the system, and is not expected
-recover or return.
-
-This function must be implemented in assembly.
-
-The first and second parameters are the same as that of ``plat_ea_handler``.
-
-The default implementation of this function calls
-``report_unhandled_exception``.
-
-Function : plat_handle_el3_ea
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Return : void
-
-This function is invoked when an External Abort is received while executing in
-EL3. Due to its critical nature, the intention of this function is to initiate
-orderly shutdown of the system, and is not expected recover or return.
-
-This function must be implemented in assembly.
-
-The default implementation of this function calls
-``report_unhandled_exception``.
-
-Build flags
------------
-
-There are some build flags which can be defined by the platform to control
-inclusion or exclusion of certain BL stages from the FIP image. These flags
-need to be defined in the platform makefile which will get included by the
-build system.
-
-- **NEED_BL33**
- By default, this flag is defined ``yes`` by the build system and ``BL33``
- build option should be supplied as a build option. The platform has the
- option of excluding the BL33 image in the ``fip`` image by defining this flag
- to ``no``. If any of the options ``EL3_PAYLOAD_BASE`` or ``PRELOADED_BL33_BASE``
- are used, this flag will be set to ``no`` automatically.
-
-C Library
----------
-
-To avoid subtle toolchain behavioral dependencies, the header files provided
-by the compiler are not used. The software is built with the ``-nostdinc`` flag
-to ensure no headers are included from the toolchain inadvertently. Instead the
-required headers are included in the TF-A source tree. The library only
-contains those C library definitions required by the local implementation. If
-more functionality is required, the needed library functions will need to be
-added to the local implementation.
-
-Some C headers have been obtained from `FreeBSD`_ and `SCC`_, while others have
-been written specifically for TF-A. Fome implementation files have been obtained
-from `FreeBSD`_, others have been written specifically for TF-A as well. The
-files can be found in ``include/lib/libc`` and ``lib/libc``.
-
-SCC can be found in http://www.simple-cc.org/. A copy of the `FreeBSD`_ sources
-can be obtained from http://github.com/freebsd/freebsd.
-
-Storage abstraction layer
--------------------------
-
-In order to improve platform independence and portability an storage abstraction
-layer is used to load data from non-volatile platform storage.
-
-Each platform should register devices and their drivers via the Storage layer.
-These drivers then need to be initialized by bootloader phases as
-required in their respective ``blx_platform_setup()`` functions. Currently
-storage access is only required by BL1 and BL2 phases. The ``load_image()``
-function uses the storage layer to access non-volatile platform storage.
-
-It is mandatory to implement at least one storage driver. For the Arm
-development platforms the Firmware Image Package (FIP) driver is provided as
-the default means to load data from storage (see the "Firmware Image Package"
-section in the `User Guide`_). The storage layer is described in the header file
-``include/drivers/io/io_storage.h``. The implementation of the common library
-is in ``drivers/io/io_storage.c`` and the driver files are located in
-``drivers/io/``.
-
-Each IO driver must provide ``io_dev_*`` structures, as described in
-``drivers/io/io_driver.h``. These are returned via a mandatory registration
-function that is called on platform initialization. The semi-hosting driver
-implementation in ``io_semihosting.c`` can be used as an example.
-
-The Storage layer provides mechanisms to initialize storage devices before
-IO operations are called. The basic operations supported by the layer
-include ``open()``, ``close()``, ``read()``, ``write()``, ``size()`` and ``seek()``.
-Drivers do not have to implement all operations, but each platform must
-provide at least one driver for a device capable of supporting generic
-operations such as loading a bootloader image.
-
-The current implementation only allows for known images to be loaded by the
-firmware. These images are specified by using their identifiers, as defined in
-``include/plat/common/common_def.h`` (or a separate header file included from
-there). The platform layer (``plat_get_image_source()``) then returns a reference
-to a device and a driver-specific ``spec`` which will be understood by the driver
-to allow access to the image data.
-
-The layer is designed in such a way that is it possible to chain drivers with
-other drivers. For example, file-system drivers may be implemented on top of
-physical block devices, both represented by IO devices with corresponding
-drivers. In such a case, the file-system "binding" with the block device may
-be deferred until the file-system device is initialised.
-
-The abstraction currently depends on structures being statically allocated
-by the drivers and callers, as the system does not yet provide a means of
-dynamically allocating memory. This may also have the affect of limiting the
-amount of open resources per driver.
-
---------------
-
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _include/plat/common/platform.h: ../include/plat/common/platform.h
-.. _include/plat/arm/common/plat_arm.h: ../include/plat/arm/common/plat_arm.h%5D
-.. _User Guide: user-guide.rst
-.. _include/plat/common/common_def.h: ../include/plat/common/common_def.h
-.. _include/plat/arm/common/arm_def.h: ../include/plat/arm/common/arm_def.h
-.. _plat/common/aarch64/platform_mp_stack.S: ../plat/common/aarch64/platform_mp_stack.S
-.. _plat/common/aarch64/platform_up_stack.S: ../plat/common/aarch64/platform_up_stack.S
-.. _For example, define the build flag in platform.mk: PLAT_PL061_MAX_GPIOS%20:=%20160
-.. _Power Domain Topology Design: psci-pd-tree.rst
-.. _include/common/bl_common.h: ../include/common/bl_common.h
-.. _include/lib/aarch32/arch.h: ../include/lib/aarch32/arch.h
-.. _Firmware Design: firmware-design.rst
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
-.. _plat/arm/board/fvp/fvp_pm.c: ../plat/arm/board/fvp/fvp_pm.c
-.. _Platform compatibility policy: ./platform-compatibility-policy.rst
-.. _IMF Design Guide: interrupt-framework-design.rst
-.. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
-.. _3.0 (GICv3): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0069b/index.html
-.. _FreeBSD: https://www.freebsd.org
-.. _SCC: http://www.simple-cc.org/
--- /dev/null
+Trusted Firmware-A Coding Guidelines
+====================================
+
+
+
+.. contents::
+
+The following sections contain TF coding guidelines. They are continually
+evolving and should not be considered "set in stone". Feel free to question them
+and provide feedback.
+
+Some of the guidelines may also apply to other codebases.
+
+**Note:** the existing TF codebase does not necessarily comply with all the
+below guidelines but the intent is for it to do so eventually.
+
+Checkpatch overrides
+--------------------
+
+Some checkpatch warnings in the TF codebase are deliberately ignored. These
+include:
+
+- ``**WARNING: line over 80 characters**``: Although the codebase should
+ generally conform to the 80 character limit this is overly restrictive in some
+ cases.
+
+- ``**WARNING: Use of volatile is usually wrong``: see
+ `Why the “volatile” type class should not be used`_ . Although this document
+ contains some very useful information, there are several legimate uses of the
+ volatile keyword within the TF codebase.
+
+Headers and inclusion
+---------------------
+
+Header guards
+^^^^^^^^^^^^^
+
+For a header file called "some_driver.h" the style used by the Trusted Firmware
+is:
+
+.. code:: c
+
+ #ifndef SOME_DRIVER_H
+ #define SOME_DRIVER_H
+
+ <header content>
+
+ #endif /* SOME_DRIVER_H */
+
+Include statement ordering
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+All header files that are included by a source file must use the following,
+grouped ordering. This is to improve readability (by making it easier to quickly
+read through the list of headers) and maintainability.
+
+#. *System* includes: Header files from the standard *C* library, such as
+ ``stddef.h`` and ``string.h``.
+
+#. *Project* includes: Header files under the ``include/`` directory within TF
+ are *project* includes.
+
+#. *Platform* includes: Header files relating to a single, specific platform,
+ and which are located under the ``plat/<platform_name>`` directory within TF,
+ are *platform* includes.
+
+Within each group, ``#include`` statements must be in alphabetical order,
+taking both the file and directory names into account.
+
+Groups must be separated by a single blank line for clarity.
+
+The example below illustrates the ordering rules using some contrived header
+file names; this type of name reuse should be otherwise avoided.
+
+.. code:: c
+
+ #include <string.h>
+
+ #include <a_dir/example/a_header.h>
+ #include <a_dir/example/b_header.h>
+ #include <a_dir/test/a_header.h>
+ #include <b_dir/example/a_header.h>
+
+ #include "./a_header.h"
+
+Include statement variants
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Two variants of the ``#include`` directive are acceptable in the TF codebase.
+Correct use of the two styles improves readability by suggesting the location
+of the included header and reducing ambiguity in cases where generic and
+platform-specific headers share a name.
+
+For header files that are in the same directory as the source file that is
+including them, use the ``"..."`` variant.
+
+For header files that are **not** in the same directory as the source file that
+is including them, use the ``<...>`` variant.
+
+Example (bl1_fwu.c):
+
+.. code:: c
+
+ #include <assert.h>
+ #include <errno.h>
+ #include <string.h>
+
+ #include "bl1_private.h"
+
+Platform include paths
+^^^^^^^^^^^^^^^^^^^^^^
+
+Platforms are allowed to add more include paths to be passed to the compiler.
+The ``PLAT_INCLUDES`` variable is used for this purpose. This is needed in
+particular for the file ``platform_def.h``.
+
+Example:
+
+.. code:: c
+
+ PLAT_INCLUDES += -Iinclude/plat/myplat/include
+
+Types and typedefs
+------------------
+
+Use of built-in *C* and *libc* data types
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The TF codebase should be kept as portable as possible, especially since both
+64-bit and 32-bit platforms are supported. To help with this, the following data
+type usage guidelines should be followed:
+
+- Where possible, use the built-in *C* data types for variable storage (for
+ example, ``char``, ``int``, ``long long``, etc) instead of the standard *C99*
+ types. Most code is typically only concerned with the minimum size of the
+ data stored, which the built-in *C* types guarantee.
+
+- Avoid using the exact-size standard *C99* types in general (for example,
+ ``uint16_t``, ``uint32_t``, ``uint64_t``, etc) since they can prevent the
+ compiler from making optimizations. There are legitimate uses for them,
+ for example to represent data of a known structure. When using them in struct
+ definitions, consider how padding in the struct will work across architectures.
+ For example, extra padding may be introduced in AArch32 systems if a struct
+ member crosses a 32-bit boundary.
+
+- Use ``int`` as the default integer type - it's likely to be the fastest on all
+ systems. Also this can be assumed to be 32-bit as a consequence of the
+ `Procedure Call Standard for the Arm Architecture`_ and the `Procedure Call
+ Standard for the Arm 64-bit Architecture`_ .
+
+- Avoid use of ``short`` as this may end up being slower than ``int`` in some
+ systems. If a variable must be exactly 16-bit, use ``int16_t`` or
+ ``uint16_t``.
+
+- Avoid use of ``long``. This is guaranteed to be at least 32-bit but, given
+ that `int` is 32-bit on Arm platforms, there is no use for it. For integers of
+ at least 64-bit, use ``long long``.
+
+- Use ``char`` for storing text. Use ``uint8_t`` for storing other 8-bit data.
+
+- Use ``unsigned`` for integers that can never be negative (counts,
+ indices, sizes, etc). TF intends to comply with MISRA "essential type" coding
+ rules (10.X), where signed and unsigned types are considered different
+ essential types. Choosing the correct type will aid this. MISRA static
+ analysers will pick up any implicit signed/unsigned conversions that may lead
+ to unexpected behaviour.
+
+- For pointer types:
+
+ - If an argument in a function declaration is pointing to a known type then
+ simply use a pointer to that type (for example: ``struct my_struct *``).
+
+ - If a variable (including an argument in a function declaration) is pointing
+ to a general, memory-mapped address, an array of pointers or another
+ structure that is likely to require pointer arithmetic then use
+ ``uintptr_t``. This will reduce the amount of casting required in the code.
+ Avoid using ``unsigned long`` or ``unsigned long long`` for this purpose; it
+ may work but is less portable.
+
+ - For other pointer arguments in a function declaration, use ``void *``. This
+ includes pointers to types that are abstracted away from the known API and
+ pointers to arbitrary data. This allows the calling function to pass a
+ pointer argument to the function without any explicit casting (the cast to
+ ``void *`` is implicit). The function implementation can then do the
+ appropriate casting to a specific type.
+
+ - Use ``ptrdiff_t`` to compare the difference between 2 pointers.
+
+- Use ``size_t`` when storing the ``sizeof()`` something.
+
+- Use ``ssize_t`` when returning the ``sizeof()`` something from a function that
+ can also return an error code; the signed type allows for a negative return
+ code in case of error. This practice should be used sparingly.
+
+- Use ``u_register_t`` when it's important to store the contents of a register
+ in its native size (32-bit in AArch32 and 64-bit in AArch64). This is not a
+ standard *C99* type but is widely available in libc implementations,
+ including the FreeBSD version included with the TF codebase. Where possible,
+ cast the variable to a more appropriate type before interpreting the data. For
+ example, the following struct in ``ep_info.h`` could use this type to minimize
+ the storage required for the set of registers:
+
+.. code:: c
+
+ typedef struct aapcs64_params {
+ u_register_t arg0;
+ u_register_t arg1;
+ u_register_t arg2;
+ u_register_t arg3;
+ u_register_t arg4;
+ u_register_t arg5;
+ u_register_t arg6;
+ u_register_t arg7;
+ } aapcs64_params_t;
+
+If some code wants to operate on ``arg0`` and knows that it represents a 32-bit
+unsigned integer on all systems, cast it to ``unsigned int``.
+
+These guidelines should be updated if additional types are needed.
+
+Avoid anonymous typedefs of structs/enums in headers
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following definition:
+
+.. code:: c
+
+ typedef struct {
+ int arg1;
+ int arg2;
+ } my_struct_t;
+
+
+is better written as:
+
+.. code:: c
+
+ struct my_struct {
+ int arg1;
+ int arg2;
+ };
+
+This allows function declarations in other header files that depend on the
+struct/enum to forward declare the struct/enum instead of including the
+entire header:
+
+.. code:: c
+
+ #include <my_struct.h>
+ void my_func(my_struct_t *arg);
+
+instead of:
+
+.. code:: c
+
+ struct my_struct;
+ void my_func(struct my_struct *arg);
+
+Some TF definitions use both a struct/enum name **and** a typedef name. This
+is discouraged for new definitions as it makes it difficult for TF to comply
+with MISRA rule 8.3, which states that "All declarations of an object or
+function shall use the same names and type qualifiers".
+
+The Linux coding standards also discourage new typedefs and checkpatch emits
+a warning for this.
+
+Existing typedefs will be retained for compatibility.
+
+Error handling and robustness
+-----------------------------
+
+Using CASSERT to check for compile time data errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Where possible, use the ``CASSERT`` macro to check the validity of data known at
+compile time instead of checking validity at runtime, to avoid unnecessary
+runtime code.
+
+For example, this can be used to check that the assembler's and compiler's views
+of the size of an array is the same.
+
+.. code:: c
+
+ #include <cassert.h>
+
+ define MY_STRUCT_SIZE 8 /* Used by assembler source files */
+
+ struct my_struct {
+ uint32_t arg1;
+ uint32_t arg2;
+ };
+
+ CASSERT(MY_STRUCT_SIZE == sizeof(struct my_struct), assert_my_struct_size_mismatch);
+
+
+If ``MY_STRUCT_SIZE`` in the above example were wrong then the compiler would
+emit an error like this:
+
+.. code:: c
+
+ my_struct.h:10:1: error: size of array ‘assert_my_struct_size_mismatch’ is negative
+
+
+Using assert() to check for programming errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In general, each secure world TF image (BL1, BL2, BL31 and BL32) should be
+treated as a tightly integrated package; the image builder should be aware of
+and responsible for all functionality within the image, even if code within that
+image is provided by multiple entities. This allows us to be more aggressive in
+interpreting invalid state or bad function arguments as programming errors using
+``assert()``, including arguments passed across platform porting interfaces.
+This is in contrast to code in a Linux environment, which is less tightly
+integrated and may attempt to be more defensive by passing the error back up the
+call stack.
+
+Where possible, badly written TF code should fail early using ``assert()``. This
+helps reduce the amount of untested conditional code. By default these
+statements are not compiled into release builds, although this can be overridden
+using the ``ENABLE_ASSERTIONS`` build flag.
+
+Examples:
+
+- Bad argument supplied to library function
+- Bad argument provided by platform porting function
+- Internal secure world image state is inconsistent
+
+
+Handling integration errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Each secure world image may be provided by a different entity (for example, a
+Trusted Boot vendor may provide the BL2 image, a TEE vendor may provide the BL32
+image and the OEM/SoC vendor may provide the other images).
+
+An image may contain bugs that are only visible when the images are integrated.
+The system integrator may not even have access to the debug variants of all the
+images in order to check if asserts are firing. For example, the release variant
+of BL1 may have already been burnt into the SoC. Therefore, TF code that detects
+an integration error should _not_ consider this a programming error, and should
+always take action, even in release builds.
+
+If an integration error is considered non-critical it should be treated as a
+recoverable error. If the error is considered critical it should be treated as
+an unexpected unrecoverable error.
+
+Handling recoverable errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** crash when supplied with bad data from an external
+source. For example, data from the normal world or a hardware device. Similarly,
+the secure world **must not** crash if it detects a non-critical problem within
+itself or the system. It must make every effort to recover from the problem by
+emitting a ``WARN`` message, performing any necessary error handling and
+continuing.
+
+Examples:
+
+- Secure world receives SMC from normal world with bad arguments.
+- Secure world receives SMC from normal world at an unexpected time.
+- BL31 receives SMC from BL32 with bad arguments.
+- BL31 receives SMC from BL32 at unexpected time.
+- Secure world receives recoverable error from hardware device. Retrying the
+ operation may help here.
+- Non-critical secure world service is not functioning correctly.
+- BL31 SPD discovers minor configuration problem with corresponding SP.
+
+Handling unrecoverable errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In some cases it may not be possible for the secure world to recover from an
+error. This situation should be handled in one of the following ways:
+
+1. If the unrecoverable error is unexpected then emit an ``ERROR`` message and
+ call ``panic()``. This will end up calling the platform-specific function
+ ``plat_panic_handler()``.
+2. If the unrecoverable error is expected to occur in certain circumstances,
+ then emit an ``ERROR`` message and call the platform-specific function
+ ``plat_error_handler()``.
+
+Cases 1 and 2 are subtly different. A platform may implement ``plat_panic_handler``
+and ``plat_error_handler`` in the same way (for example, by waiting for a secure
+watchdog to time-out or by invoking an interface on the platform's power
+controller to reset the platform). However, ``plat_error_handler`` may take
+additional action for some errors (for example, it may set a flag so the
+platform resets into a different mode). Also, ``plat_panic_handler()`` may
+implement additional debug functionality (for example, invoking a hardware
+breakpoint).
+
+Examples of unexpected unrecoverable errors:
+
+- BL32 receives an unexpected SMC response from BL31 that it is unable to
+ recover from.
+- BL31 Trusted OS SPD code discovers that BL2 has not loaded the corresponding
+ Trusted OS, which is critical for platform operation.
+- Secure world discovers that a critical hardware device is an unexpected and
+ unrecoverable state.
+- Secure world receives an unexpected and unrecoverable error from a critical
+ hardware device.
+- Secure world discovers that it is running on unsupported hardware.
+
+Examples of expected unrecoverable errors:
+
+- BL1/BL2 fails to load the next image due to missing/corrupt firmware on disk.
+- BL1/BL2 fails to authenticate the next image due to an invalid certificate.
+- Secure world continuously receives recoverable errors from a hardware device
+ but is unable to proceed without a valid response.
+
+Handling critical unresponsiveness
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If the secure world is waiting for a response from an external source (for
+example, the normal world or a hardware device) which is critical for continued
+operation, it must not wait indefinitely. It must have a mechanism (for example,
+a secure watchdog) for resetting itself and/or the external source to prevent
+the system from executing in this state indefinitely.
+
+Examples:
+
+- BL1 is waiting for the normal world to raise an SMC to proceed to the next
+ stage of the secure firmware update process.
+- A Trusted OS is waiting for a response from a proxy in the normal world that
+ is critical for continued operation.
+- Secure world is waiting for a hardware response that is critical for continued
+ operation.
+
+Security considerations
+-----------------------
+
+Part of the security of a platform is handling errors correctly, as described in
+the previous section. There are several other security considerations covered in
+this section.
+
+Do not leak secrets to the normal world
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **must not** leak secrets to the normal world, for example in
+response to an SMC.
+
+Handling Denial of Service attacks
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The secure world **should never** crash or become unusable due to receiving too
+many normal world requests (a *Denial of Service* or *DoS* attack). It should
+have a mechanism for throttling or ignoring normal world requests.
+
+Performance considerations
+--------------------------
+
+Avoid printf and use logging macros
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+``debug.h`` provides logging macros (for example, ``WARN`` and ``ERROR``)
+which wrap ``tf_log`` and which allow the logging call to be compiled-out
+depending on the ``make`` command. Use these macros to avoid print statements
+being compiled unconditionally into the binary.
+
+Each logging macro has a numerical log level:
+
+.. code:: c
+
+ #define LOG_LEVEL_NONE 0
+ #define LOG_LEVEL_ERROR 10
+ #define LOG_LEVEL_NOTICE 20
+ #define LOG_LEVEL_WARNING 30
+ #define LOG_LEVEL_INFO 40
+ #define LOG_LEVEL_VERBOSE 50
+
+
+By default, all logging statements with a log level ``<= LOG_LEVEL_INFO`` will
+be compiled into debug builds and all statements with a log level
+``<= LOG_LEVEL_NOTICE`` will be compiled into release builds. This can be
+overridden from the command line or by the platform makefile (although it may be
+necessary to clean the build directory first). For example, to enable
+``VERBOSE`` logging on FVP:
+
+``make PLAT=fvp LOG_LEVEL=50 all``
+
+Use const data where possible
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+For example, the following code:
+
+.. code:: c
+
+ struct my_struct {
+ int arg1;
+ int arg2;
+ };
+
+ void init(struct my_struct *ptr);
+
+ void main(void)
+ {
+ struct my_struct x;
+ x.arg1 = 1;
+ x.arg2 = 2;
+ init(&x);
+ }
+
+is better written as:
+
+.. code:: c
+
+ struct my_struct {
+ int arg1;
+ int arg2;
+ };
+
+ void init(const struct my_struct *ptr);
+
+ void main(void)
+ {
+ const struct my_struct x = { 1, 2 };
+ init(&x);
+ }
+
+This allows the linker to put the data in a read-only data section instead of a
+writeable data section, which may result in a smaller and faster binary. Note
+that this may require dependent functions (``init()`` in the above example) to
+have ``const`` arguments, assuming they don't need to modify the data.
+
+Library and driver code
+-----------------------
+
+TF library code (under ``lib/`` and ``include/lib``) is any code that provides a
+reusable interface to other code, potentially even to code outside of TF.
+
+In some systems drivers must conform to a specific driver framework to provide
+services to the rest of the system. TF has no driver framework and the
+distinction between a driver and library is somewhat subjective.
+
+A driver (under ``drivers/`` and ``include/drivers/``) is defined as code that
+interfaces with hardware via a memory mapped interface.
+
+Some drivers (for example, the Arm CCI driver in ``include/drivers/arm/cci.h``)
+provide a general purpose API to that specific hardware. Other drivers (for
+example, the Arm PL011 console driver in ``drivers/arm/pl011/pl011_console.S``)
+provide a specific hardware implementation of a more abstract library API. In
+the latter case there may potentially be multiple drivers for the same hardware
+device.
+
+Neither libraries nor drivers should depend on platform-specific code. If they
+require platform-specific data (for example, a base address) to operate then
+they should provide an initialization function that takes the platform-specific
+data as arguments.
+
+TF common code (under ``common/`` and ``include/common/``) is code that is re-used
+by other generic (non-platform-specific) TF code. It is effectively internal
+library code.
+
+.. _`Why the “volatile” type class should not be used`: https://www.kernel.org/doc/html/latest/process/volatile-considered-harmful.html
+.. _`Procedure Call Standard for the Arm Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042f/IHI0042F_aapcs.pdf
+.. _`Procedure Call Standard for the Arm 64-bit Architecture`: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
--- /dev/null
+Contributing to Trusted Firmware-A
+==================================
+
+Getting Started
+---------------
+
+- Make sure you have a Github account and you are logged on
+ `developer.trustedfirmware.org`_.
+- Create an `issue`_ for your work if one does not already exist. This gives
+ everyone visibility of whether others are working on something similar.
+
+ - If you intend to include Third Party IP in your contribution, please
+ raise a separate `issue`_ for this and ensure that the changes that
+ include Third Party IP are made on a separate topic branch.
+
+- Clone `arm-trusted-firmware-a`_ on your own machine as suggested on the
+ `User Guide`_.
+- Create a local topic branch based on the `arm-trusted-firmware-a`_ ``master``
+ branch.
+
+Making Changes
+--------------
+
+- Make commits of logical units. See these general `Git guidelines`_ for
+ contributing to a project.
+- Follow the `Coding Guidelines`_.
+
+ - Use the checkpatch.pl script provided with the Linux source tree. A
+ Makefile target is provided for convenience (see the "Checking source code
+ style" section in the `User Guide`_).
+
+- Keep the commits on topic. If you need to fix another bug or make another
+ enhancement, please create a separate `issue`_ and address it on a separate
+ topic branch.
+- Avoid long commit series. If you do have a long series, consider whether
+ some commits should be squashed together or addressed in a separate topic.
+- Make sure your commit messages are in the proper format. If a commit fixes
+ an `issue`_, include a reference.
+- Where appropriate, please update the documentation.
+
+ - Consider whether the `User Guide`_, `Porting Guide`_, `Firmware Design`_
+ or other in-source documentation needs updating.
+ - Ensure that each changed file has the correct copyright and license
+ information. Files that entirely consist of contributions to this
+ project should have a copyright notice and BSD-3-Clause SPDX license
+ identifier of the form as shown in `license.rst`_. Files that contain
+ changes to imported Third Party IP files should retain their original
+ copyright and license notices. For significant contributions you may
+ add your own copyright notice in following format:
+
+ ::
+
+ Portions copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
+
+ where XXXX is the year of first contribution (if different to YYYY) and
+ YYYY is the year of most recent contribution. <OWNER> is your name or
+ your company name.
+ - If you are submitting new files that you intend to be the technical
+ sub-maintainer for (for example, a new platform port), then also update
+ the `Maintainers`_ file.
+ - For topics with multiple commits, you should make all documentation
+ changes (and nothing else) in the last commit of the series. Otherwise,
+ include the documentation changes within the single commit.
+
+- Please test your changes. As a minimum, ensure that Linux boots on the
+ Foundation FVP. See `Running the software on FVP`_ for more information. For
+ more extensive testing, consider running the `TF-A Tests`_ against your
+ patches.
+
+Submitting Changes
+------------------
+
+- Ensure that each commit in the series has at least one ``Signed-off-by:``
+ line, using your real name and email address. The names in the
+ ``Signed-off-by:`` and ``Author:`` lines must match. If anyone else
+ contributes to the commit, they must also add their own ``Signed-off-by:``
+ line. By adding this line the contributor certifies the contribution is made
+ under the terms of the `Developer Certificate of Origin (DCO)`_.
+
+ More details may be found in the `Gerrit Signed-off-by Lines guidelines`_.
+
+- Ensure that each commit also has a unique ``Change-Id:`` line. If you have
+ cloned the repository with the "`Clone with commit-msg hook`" clone method
+ (as advised on the `User Guide`_), this should already be the case.
+
+ More details may be found in the `Gerrit Change-Ids documentation`_.
+
+- Submit your changes for review at https://review.trustedfirmware.org
+ targeting the ``integration`` branch.
+
+ - The changes will then undergo further review and testing by the
+ `Maintainers`_. Any review comments will be made directly on your patch.
+ This may require you to do some rework.
+
+ Refer to the `Gerrit Uploading Changes documentation`_ for more details.
+
+- When the changes are accepted, the `Maintainers`_ will integrate them.
+
+ - Typically, the `Maintainers`_ will merge the changes into the
+ ``integration`` branch.
+ - If the changes are not based on a sufficiently-recent commit, or if they
+ cannot be automatically rebased, then the `Maintainers`_ may rebase it on
+ the ``master`` branch or ask you to do so.
+ - After final integration testing, the changes will make their way into the
+ ``master`` branch. If a problem is found during integration, the merge
+ commit will be removed from the ``integration`` branch and the
+ `Maintainers`_ will ask you to create a new patch set to resolve the
+ problem.
+
+Binary Components
+-----------------
+
+- Platforms may depend on binary components submitted to the `Trusted Firmware
+ binary repository`_ if they require code that the contributor is unable or
+ unwilling to open-source. This should be used as a rare exception.
+- All binary components must follow the contribution guidelines (in particular
+ licensing rules) outlined in the `readme.rst <tf-binaries-readme_>`_ file of
+ the binary repository.
+- Binary components must be restricted to only the specific functionality that
+ cannot be open-sourced and must be linked into a larger open-source platform
+ port. The majority of the platform port must still be implemented in open
+ source. Platform ports that are merely a thin wrapper around a binary
+ component that contains all the actual code will not be accepted.
+- Only platform port code (i.e. in the ``plat/<vendor>`` directory) may rely on
+ binary components. Generic code must always be fully open-source.
+
+--------------
+
+*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
+.. _issue: https://developer.trustedfirmware.org/project/board/1/
+.. _arm-trusted-firmware-a: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
+.. _Git guidelines: http://git-scm.com/book/ch5-2.html
+.. _Coding Guidelines: ./docs/coding-guidelines.rst
+.. _User Guide: ./docs/user-guide.rst
+.. _Porting Guide: ./docs/porting-guide.rst
+.. _Firmware Design: ./docs/firmware-design.rst
+.. _license.rst: ./license.rst
+.. _Acknowledgements: ./acknowledgements.rst
+.. _Maintainers: ./maintainers.rst
+.. _Running the software on FVP: ./docs/user-guide.rst#user-content-running-the-software-on-fvp
+.. _Developer Certificate of Origin (DCO): ./dco.txt
+.. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
+.. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
+.. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
+.. _TF-A Tests: https://git.trustedfirmware.org/TF-A/tf-a-tests.git/about/
+.. _Trusted Firmware binary repository: https://review.trustedfirmware.org/admin/repos/tf-binaries
+.. _tf-binaries-readme: https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst
--- /dev/null
+Frequently-Asked Questions (FAQ)
+================================
+
+How do I update my changes?
+---------------------------
+
+Often it is necessary to update your patch set before it is merged. Refer to the
+`Gerrit Upload Patch Set documentation`_ on how to do so.
+
+If you need to modify an existing patch set with multiple commits, refer to the
+`Gerrit Replace Changes documentation`_.
+
+How long will my changes take to merge into ``integration``?
+------------------------------------------------------------
+
+This can vary a lot, depending on:
+
+* How important the patch set is considered by the TF maintainers. Where
+ possible, you should indicate the required timescales for merging the patch
+ set and the impact of any delay. Feel free to add a comment to your patch set
+ to get an estimate of when it will be merged.
+
+* The quality of the patch set. Patches are likely to be merged more quickly if
+ they follow the coding guidelines, have already had some code review, and have
+ been appropriately tested.
+
+* The impact of the patch set. For example, a patch that changes a key generic
+ API is likely to receive much greater scrutiny than a local change to a
+ specific platform port.
+
+* How much opportunity for external review is required. For example, the TF
+ maintainers may not wait for external review comments to merge trivial
+ bug-fixes but may wait up to a week to merge major changes, or ones requiring
+ feedback from specific parties.
+
+* How many other patch sets are waiting to be integrated and the risk of
+ conflict between the topics.
+
+* If there is a code freeze in place in preparation for the release. Please
+ refer the `release information`_ for more details.
+
+* The workload of the TF maintainers.
+
+How long will it take for my changes to go from ``integration`` to ``master``?
+------------------------------------------------------------------------------
+
+This depends on how many concurrent patches are being processed at the same
+time. In simple cases where all potential regressions have already been tested,
+the delay will be less than 1 day. If the TF maintainers are trying to merge
+several things over the course of a few days, it might take up to a week.
+Typically, it will be 1-2 days.
+
+The worst case is if the TF maintainers are trying to make a release while also
+receiving patches that will not be merged into the release. In this case, the
+patches will be merged onto ``integration``, which will temporarily diverge from
+the release branch. The ``integration`` branch will be rebased onto ``master``
+after the release, and then ``master`` will be fast-forwarded to ``integration``
+1-2 days later. This whole process could take up 4 weeks. Please refer the
+`release information`_ for code freeze dates. The TF maintainers will inform the
+patch owner if this is going to happen.
+
+It is OK to create a patch based on commits that are only available in
+``integration`` or another patch set, rather than ``master``. There is a risk
+that the dependency commits will change (for example due to patch set rework or
+integration problems). If this happens, the dependent patch will need reworking.
+
+What are these strange comments in my changes?
+----------------------------------------------
+
+All the comments from ``ci-bot-user`` are associated with Continuous Integration
+infrastructure. The links published on the comment are not currently accessible,
+but would be after the CI has been transitioned to `trustedfirmware.org`_.
+Please refer to https://github.com/ARM-software/tf-issues/issues/681 for more
+details on the timelines.
+
+.. _release information: release-information.rst
+.. _Gerrit Upload Patch Set documentation: https://review.trustedfirmware.org/Documentation/intro-user.html#upload-patch-set
+.. _Gerrit Replace Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html#push_replace
+.. _trustedfirmware.org: https://www.trustedfirmware.org/
--- /dev/null
+Processes & Policies
+====================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+ :numbered:
+
+ release-information
+ security-center
+ platform-compatibility-policy
+ coding-guidelines
+ contributing
+ faq
--- /dev/null
+TF-A Platform Compatibility Policy
+==================================
+
+
+
+
+.. contents::
+
+--------------
+
+Introduction
+------------
+
+This document clarifies the project's policy around compatibility for upstream
+platforms.
+
+Platform compatibility policy
+-----------------------------
+
+Platform compatibility is mainly affected by changes to Platform APIs (as
+documented in the `Porting Guide`_), driver APIs (like the GICv3 drivers) or
+library interfaces (like xlat_table library). The project will try to maintain
+compatibility for upstream platforms. Due to evolving requirements and
+enhancements, there might be changes affecting platform compatibility which
+means the previous interface needs to be deprecated and a new interface
+introduced to replace it. In case the migration to the new interface is trivial,
+the contributor of the change is expected to make good effort to migrate the
+upstream platforms to the new interface.
+
+The `Release information`_ documents the deprecated interfaces and the intended
+release after which it will be removed. When an interface is deprecated, the
+page must be updated to indicate the release after which the interface will be
+removed. This must be at least 1 full release cycle in future. For non-trivial
+interface changes, a `tf-issue`_ should be posted to notify platforms that they
+should migrate away from the deprecated interfaces. Platforms are expected to
+migrate before the removal of the deprecated interface.
+
+--------------
+
+*Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.*
+
+.. _Porting Guide: ../getting_started/porting-guide.rst
+.. _Release information: https://github.com/ARM-software/arm-trusted-firmware/wiki/TF-A-Release-information#removal-of-deprecated-interfaces
+.. _tf-issue: https://github.com/ARM-software/tf-issues/issues
--- /dev/null
+TF-A Release Information
+========================
+
+.. section-numbering::
+ :suffix: .
+
+.. contents::
+
+--------------
+
+Project Release Cadence
+-----------------------
+
+The project currently aims to do a release once every 6 months which will be
+tagged on the master branch. There will be a code freeze (stop merging
+non-essential PRs) up to 4 weeks prior to the target release date. The release
+candidates will start appearing after this and only bug fixes or updates
+required for the release will be merged. The maintainers are free to use their
+judgement on what PRs are essential for the release. A release branch may be
+created after code freeze if there are significant PRs that need merging onto
+the integration branch during the merge window.
+
+The release testing will be performed on release candidates and depending on
+issues found, additional release candidates may be created to fix the issues.
+
+::
+
+ |<----------6 months---------->|
+ |<---4 weeks--->| |<---4 weeks--->|
+ +-----------------------------------------------------------> time
+ | | | |
+ code freeze ver w.x code freeze ver y.z
+
+
+Upcoming Releases
+~~~~~~~~~~~~~~~~~
+
+These are the estimated dates for the upcoming release. These may change
+depending on project requirement and partner feedback.
+
++-----------------+---------------------------+------------------------------+
+| Release Version | Target Date | Expected Code Freeze |
++=================+===========================+==============================+
+| v2.0 | 1st week of Oct '18 | 1st week of Sep '18 |
++-----------------+---------------------------+------------------------------+
+| v2.1 | 5th week of Mar '19 | 1st week of Mar '19 |
++-----------------+---------------------------+------------------------------+
+
+Removal of Deprecated Interfaces
+--------------------------------
+
+As mentioned in the `Platform compatibility policy`_, this is a live document
+cataloging all the deprecated interfaces in TF-A project and the Release version
+after which it will be removed.
+
++--------------------------------+-------------+---------+---------------------------------------------------------+
+| Interface | Deprecation | Removed | Comments |
+| | Date | after | |
+| | | Release | |
++================================+=============+=========+=========================================================+
+| Legacy Console API | Jan '18 | v2.1 | Deprecated in favour of ``MULTI_CONSOLE_API`` |
++--------------------------------+-------------+---------+---------------------------------------------------------+
+| Weak default | Oct '18 | v2.1 | The default implementations are defined in |
+| ``plat_crash_console_*`` | | | `crash_console_helpers.S`_. The platforms have to |
+| APIs | | | define ``plat_crash_console_*``. |
++--------------------------------+-------------+---------+---------------------------------------------------------+
+| ``finish_console_register`` | Oct '18 | v2.1 | The old version of the macro is deprecated. See commit |
+| macro in | | | cc5859c_ for more details. |
+| ``MULTI_CONSOLE_API`` | | | |
++--------------------------------+-------------+---------+---------------------------------------------------------+
+| Types ``tzc_action_t`` and | Oct '18 | v2.1 | Using logical operations such as OR in enumerations |
+| ``tzc_region_attributes_t`` | | | goes against the MISRA guidelines. |
++--------------------------------+-------------+---------+---------------------------------------------------------+
+| Macro ``EL_IMPLEMENTED()`` | Oct '18 | v2.1 | Deprecated in favour of ``el_implemented()``. |
++--------------------------------+-------------+---------+---------------------------------------------------------+
+| ``get_afflvl_shift()``, | Dec '18 | v2.1 | Removed. |
+| ``mpidr_mask_lower_afflvls()``,| | | |
+| and ``eret()``. | | | |
++--------------------------------+-------------+---------+---------------------------------------------------------+
+| Extra include paths in the | Jan '18 | v2.1 | Now it is needed to use the full path of the common |
+| Makefile in ``INCLUDES``. | | | header files. More information in commit 09d40e0e0828_. |
++--------------------------------+-------------+---------+---------------------------------------------------------+
+
+*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _Platform compatibility policy: platform-compatibility-policy.rst
+.. _crash_console_helpers.S: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/common/aarch64/crash_console_helpers.S
+.. _cc5859c: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=cc5859ca19ff546c35eb0331000dae090b6eabcf
+.. _09d40e0e0828: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=09d40e0e08283a249e7dce0e106c07c5141f9b7e
--- /dev/null
+Security Center
+===============
+
+Security Disclosures
+--------------------
+
+We disclose all security vulnerabilities we find or are advised about that are
+relevant for ARM Trusted Firmware (TF). We encourage responsible disclosure of
+vulnerabilities and inform users as best we can about all possible issues.
+
+We disclose TF vulnerabilities as Security Advisories. These are listed at the
+bottom of this page and announced as issues in the `GitHub issue tracker`_ with
+the "security-advisory" tag. You can receive notification emails for these by
+watching that project.
+
+Found a Security Issue?
+-----------------------
+
+Although we try to keep TF secure, we can only do so with the help of the
+community of developers and security researchers.
+
+If you think you have found a security vulnerability, please *do not* report it
+in the `GitHub issue tracker`_. Instead send an email to
+
+Please include:
+
+* Trusted Firmware version (or commit) affected
+
+* A description of the concern or vulnerability
+
+* Details on how to replicate the vulnerability, including:
+
+ - Configuration details
+
+ - Proof of concept exploit code
+
+ - Any additional software or tools required
+
+We recommend using `this PGP/GPG key`_ for encrypting the information. This key
+is also available at http://keyserver.pgp.com and LDAP port 389 of the same
+server. The fingerprint for this key is:
+
+::
+
+ 1309 2C19 22B4 8E87 F17B FE5C 3AB7 EFCB 45A0 DFD0
+
+If you would like replies to be encrypted, please provide your public key.
+
+Please give us the time to respond to you and fix the vulnerability before going
+public. We do our best to respond and fix any issues quickly. We also need to
+ensure providers of products that use TF have a chance to consider the
+implications of the vulnerability and its remedy.
+
+Afterwards, we encourage you to write-up your findings about the TF source code.
+
+Attribution
+-----------
+
+We will name and thank you in the ``change-log.rst`` distributed with the source
+code and in any published security advisory.
+
+Security Advisories
+-------------------
+
++-----------+------------------------------------------------------------------+
+| ID | Title |
++===========+==================================================================+
+| `TFV-1`_ | Malformed Firmware Update SMC can result in copy of unexpectedly |
+| | large data into secure memory |
++-----------+------------------------------------------------------------------+
+| `TFV-2`_ | Enabled secure self-hosted invasive debug interface can allow |
+| | normal world to panic secure world |
++-----------+------------------------------------------------------------------+
+| `TFV-3`_ | RO memory is always executable at AArch64 Secure EL1 |
++-----------+------------------------------------------------------------------+
+| `TFV-4`_ | Malformed Firmware Update SMC can result in copy or |
+| | authentication of unexpected data in secure memory in AArch32 |
+| | state |
++-----------+------------------------------------------------------------------+
+| `TFV-5`_ | Not initializing or saving/restoring PMCR_EL0 can leak secure |
+| | world timing information |
++-----------+------------------------------------------------------------------+
+| `TFV-6`_ | Arm Trusted Firmware exposure to speculative processor |
+| | vulnerabilities using cache timing side-channels |
++-----------+------------------------------------------------------------------+
+| `TFV-7`_ | Trusted Firmware-A exposure to cache speculation vulnerability |
+| | Variant 4 |
++-----------+------------------------------------------------------------------+
+| `TFV-8`_ | Not saving x0 to x3 registers can leak information from one |
+| | Normal World SMC client to another |
++-----------+------------------------------------------------------------------+
+
+.. _GitHub issue tracker: https://github.com/ARM-software/tf-issues/issues
+.. _this PGP/GPG key: security-reporting.asc
+.. _TFV-1: ./security_advisories/security-advisory-tfv-1.rst
+.. _TFV-2: ./security_advisories/security-advisory-tfv-2.rst
+.. _TFV-3: ./security_advisories/security-advisory-tfv-3.rst
+.. _TFV-4: ./security_advisories/security-advisory-tfv-4.rst
+.. _TFV-5: ./security_advisories/security-advisory-tfv-5.rst
+.. _TFV-6: ./security_advisories/security-advisory-tfv-6.rst
+.. _TFV-7: ./security_advisories/security-advisory-tfv-7.rst
+.. _TFV-8: ./security_advisories/security-advisory-tfv-8.rst
--- /dev/null
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: PGP Desktop 10.2.0 (Build 2317)
+
+mQENBFey/QMBCACyxJaLsMYU794ZfzLdY172tHXRJfP0X3b34HU35G7kYl1zNiYc
+/NoygtQdtDv/aW1B2A/YTNhGge+gX4BWAREd5CYDbdPEoMWC395/qbnmMmez7YNY
+PEJ9Iq9e5AayAWwZTL1zgKwdvE+WTwWok/nMbsifJSEdhdrOIHNqRcZgplUUyZ2R
+sDqFtSbACO3xj4Psk8KJ23Ax7UZgULouZOJaHOnyq8F9V/U7zWvX4Odf96XaC1Em
+cUTsG0kQfa7Y4Hqqjzowq366I4k2o2LAtuLPWNCvq5jjEceLs2+qV4cNLgyL2dzO
+wtUL6EdkrGfkxsPHpsVKXig4wjeX9ehCSqRlABEBAAG0PVRydXN0ZWQgRmlybXdh
+cmUgU2VjdXJpdHkgPHRydXN0ZWQtZmlybXdhcmUtc2VjdXJpdHlAYXJtLmNvbT6J
+AYwEEAECAHYFAley/SEwFIAAAAAAIAAHcHJlZmVycmVkLWVtYWlsLWVuY29kaW5n
+QHBncC5jb21wZ3BtaW1lCAsJCAcDAgEKAhkBGRhsZGFwOi8va2V5c2VydmVyLnBn
+cC5jb20FGwMAAAAFFgADAgEFHgEAAAAGFQgJCgMCAAoJEDq378tFoN/QFJsH/0ly
+H91LYYzKIQrbolQw7Rp47lgzH88uN1rInYpW2GaTbjwPffAhYJ4VsN8RaiFskD9m
+DjMg4vY8p0jPTCUX1Acq20Wq0Ybv3HcrtjUp4ie0+rLUi3043yJyKFMWkJC2Kr+p
+SobnxSrAie4HDFUgSaPoh9Qf1zXEzOavdgcziMiyS5iVUf6NXYZ9z82OTZ6TdPKS
+u+L5zOHTdrV3+hD54w00Xa+EIE7u4v0to6Uwm977508hyGuvpOVq+u7+S3qJQvnY
++JheStbgLsm6CyoRjyrlTE01ujAD6hI6Ef9yMgEljOBEy4phKAJ67SCRLEOiCp5U
+YHFCULwhzIyg2y3WmZSJASIEEAECAAwFAlezAnwFAwASdQAACgkQlxC4m8pXrXzd
+GAf/T8YEICI9qQt2vnCtCbBvVaTc2sAphVZ51kZVDqCDPB7znDtJYRBpi/9IPELt
+mYwIElMx2mqmahVaeUghmbzmcLZe8QHUi8GanO1mh+ook6uyjRojSIq6VUVV5uUf
+tuscfhpilOvUclqMqYEIgXfl08YwS40Kmmj0qokwad0co0zGQ8GEhlgMi2yvJfiG
+fPS0Xcn1J0980E/VgJQCAKwZvukrbb32WVwuhgepqs/4/62PZNxglcErioFt6P0A
+ik4t9Hr0uErqCeEKiYtmEw5e9ioRdX7CV+tJgIk907Tpv6E0iDFRJHmJBvmsz82O
+stOazS3wZ5Xck7asTqkvoyo9Z7kBDQRXsv0DAQgAsmL1UUIWyoNmYJWixSPDmclP
+0ul3T1FCOsIlWTeVeshnHByYdgZOfce78ETCUoq8G7qvYm4GRrEDpqVbxqTxJioP
+4Li05WDdNCKzSoqWd8ADA48gYnnJEu2NhA7ZkEC6u3+Mdbmd3M0J6nsAWeE0BV1p
+F5zI600sJuoH2QNWB7Kv5N3GCFE4IgCIH8MwDo4Y4FTZtygx4GjEtSExiOIz+bpX
+2+GkFCQGpIyLHLP4FmQmrsNzsIdEyFuG0IdoVuQ2PtNLiw+Wkm7CXWgRmFx/dtPN
+eVnOFWdbTtjBWVv/Z6zbANos2knfc75KR4FCQ6pWRvVeJuMuMopUDkfFDMtR8QAR
+AQABiQJBBBgBAgErBQJXsv0EBRsMAAAAwF0gBBkBCAAGBQJXsv0DAAoJENaB8ph8
+s9hu/nsH/Rx696ZR+1vZi5qCTUwo6s0Qa15x4OuyJEM85VgMLVY7/MZpp1Y8If6u
+A5BynQpy4QIPxIRsRx6twduW9/gb8UVhpMRPyuJ+5sSv0/KeUqkPbKSUGro2zGlR
+sjqPrchi6uafWZqOR/y/DNkEvkgZZaP+f9xs2qWKuoF08yTioo76QoroA4DVuVAT
+MkDFe9d3natAmfmjO4kvxuthg3y7R+sdXrCHpYYJZdbiR6gyj7e8whlSLwHQT3lz
+7QBL/CvVvL/dmhu5pk8fsksbehepMQTkCJ6GGEamOPEhwh7IvlzhEt97U4uzjuMd
+BPjqOCes+4QTmn/+lMTySG0kXxnHOEUACgkQOrfvy0Wg39D8Jgf/Uf3epkMOJ9xm
+N1l5vW8tQQ6RR055YQxQ9P6JMyCQGEJmGOcvrasCho69wMQDy4AYVtJaZd25LH/3
+LX/lcyDOP4C9VYXM+IxlcaRmjBKqWx9UzQeeioIkfmjMpJFU846ZP1dacge0lPx8
+p6ocPbM0rkv0xuF/dwkDQd4BPSmv4/3/UM8FRoYo8Q7SHkDR98wJ8FCm6k9wRtWC
+K/jzmBswY2TewAHom3jLzTM0FZ/n5Sini3EGAI2EvnQrxWRpeE7ZOkHKqLHEOaHl
+zeST4U/cUgxhwgnhbGJ7zmrFsHpYnnZYM3mIKfQ3/EhksZ68TF9IB1tfUiQTij4r
+9jWa0ybRdQ==
+=nZZb
+-----END PGP PUBLIC KEY BLOCK-----
+++ /dev/null
-PSCI Library Integration guide for Armv8-A AArch32 systems
-==========================================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-This document describes the PSCI library interface with a focus on how to
-integrate with a suitable Trusted OS for an Armv8-A AArch32 system. The PSCI
-Library implements the PSCI Standard as described in `PSCI spec`_ and is meant
-to be integrated with EL3 Runtime Software which invokes the PSCI Library
-interface appropriately. **EL3 Runtime Software** refers to software executing
-at the highest secure privileged mode, which is EL3 in AArch64 or Secure SVC/
-Monitor mode in AArch32, and provides runtime services to the non-secure world.
-The runtime service request is made via SMC (Secure Monitor Call) and the call
-must adhere to `SMCCC`_. In AArch32, EL3 Runtime Software may additionally
-include Trusted OS functionality. A minimal AArch32 Secure Payload, SP-MIN, is
-provided in Trusted Firmware-A (TF-A) to illustrate the usage and integration
-of the PSCI library. The description of PSCI library interface and its
-integration with EL3 Runtime Software in this document is targeted towards
-AArch32 systems.
-
-Generic call sequence for PSCI Library interface (AArch32)
-----------------------------------------------------------
-
-The generic call sequence of PSCI Library interfaces (see
-`PSCI Library Interface`_) during cold boot in AArch32
-system is described below:
-
-#. After cold reset, the EL3 Runtime Software performs its cold boot
- initialization including the PSCI library pre-requisites mentioned in
- `PSCI Library Interface`_, and also the necessary platform
- setup.
-
-#. Call ``psci_setup()`` in Monitor mode.
-
-#. Optionally call ``psci_register_spd_pm_hook()`` to register callbacks to
- do bookkeeping for the EL3 Runtime Software during power management.
-
-#. Call ``psci_prepare_next_non_secure_ctx()`` to initialize the non-secure CPU
- context.
-
-#. Get the non-secure ``cpu_context_t`` for the current CPU by calling
- ``cm_get_context()`` , then programming the registers in the non-secure
- context and exiting to non-secure world. If the EL3 Runtime Software needs
- additional configuration to be set for non-secure context, like routing
- FIQs to the secure world, the values of the registers can be modified prior
- to programming. See `PSCI CPU context management`_ for more
- details on CPU context management.
-
-The generic call sequence of PSCI library interfaces during warm boot in
-AArch32 systems is described below:
-
-#. After warm reset, the EL3 Runtime Software performs the necessary warm
- boot initialization including the PSCI library pre-requisites mentioned in
- `PSCI Library Interface`_ (Note that the Data cache
- **must not** be enabled).
-
-#. Call ``psci_warmboot_entrypoint()`` in Monitor mode. This interface
- initializes/restores the non-secure CPU context as well.
-
-#. Do step 5 of the cold boot call sequence described above.
-
-The generic call sequence of PSCI library interfaces on receipt of a PSCI SMC
-on an AArch32 system is described below:
-
-#. On receipt of an SMC, save the register context as per `SMCCC`_.
-
-#. If the SMC function identifier corresponds to a SMC32 PSCI API, construct
- the appropriate arguments and call the ``psci_smc_handler()`` interface.
- The invocation may or may not return back to the caller depending on
- whether the PSCI API resulted in power down of the CPU.
-
-#. If ``psci_smc_handler()`` returns, populate the return value in R0 (AArch32)/
- X0 (AArch64) and restore other registers as per `SMCCC`_.
-
-PSCI CPU context management
----------------------------
-
-PSCI library is in charge of initializing/restoring the non-secure CPU system
-registers according to `PSCI specification`_ during cold/warm boot.
-This is referred to as ``PSCI CPU Context Management``. Registers that need to
-be preserved across CPU power down/power up cycles are maintained in
-``cpu_context_t`` data structure. The initialization of other non-secure CPU
-system registers which do not require coordination with the EL3 Runtime
-Software is done directly by the PSCI library (see ``cm_prepare_el3_exit()``).
-
-The EL3 Runtime Software is responsible for managing register context
-during switch between Normal and Secure worlds. The register context to be
-saved and restored depends on the mechanism used to trigger the world switch.
-For example, if the world switch was triggered by an SMC call, then the
-registers need to be saved and restored according to `SMCCC`_. In AArch64,
-due to the tight integration with BL31, both BL31 and PSCI library
-use the same ``cpu_context_t`` data structure for PSCI CPU context management
-and register context management during world switch. This cannot be assumed
-for AArch32 EL3 Runtime Software since most AArch32 Trusted OSes already implement
-a mechanism for register context management during world switch. Hence, when
-the PSCI library is integrated with a AArch32 EL3 Runtime Software, the
-``cpu_context_t`` is stripped down for just PSCI CPU context management.
-
-During cold/warm boot, after invoking appropriate PSCI library interfaces, it
-is expected that the EL3 Runtime Software will query the ``cpu_context_t`` and
-write appropriate values to the corresponding system registers. This mechanism
-resolves 2 additional problems for AArch32 EL3 Runtime Software:
-
-#. Values for certain system registers like SCR and SCTLR cannot be
- unilaterally determined by PSCI library and need inputs from the EL3
- Runtime Software. Using ``cpu_context_t`` as an intermediary data store
- allows EL3 Runtime Software to modify the register values appropriately
- before programming them.
-
-#. The PSCI library provides appropriate LR and SPSR values (entrypoint
- information) for exit into non-secure world. Using ``cpu_context_t`` as an
- intermediary data store allows the EL3 Runtime Software to store these
- values safely until it is ready for exit to non-secure world.
-
-Currently the ``cpu_context_t`` data structure for AArch32 stores the following
-registers: R0 - R3, LR (R14), SCR, SPSR, SCTLR.
-
-The EL3 Runtime Software must implement accessors to get/set pointers
-to CPU context ``cpu_context_t`` data and these are described in
-`CPU Context management API`_.
-
-PSCI Library Interface
-----------------------
-
-The PSCI library implements the `PSCI Specification`_. The interfaces
-to this library are declared in ``psci_lib.h`` and are as listed below:
-
-.. code:: c
-
- u_register_t psci_smc_handler(uint32_t smc_fid, u_register_t x1,
- u_register_t x2, u_register_t x3,
- u_register_t x4, void *cookie,
- void *handle, u_register_t flags);
- int psci_setup(const psci_lib_args_t *lib_args);
- void psci_warmboot_entrypoint(void);
- void psci_register_spd_pm_hook(const spd_pm_ops_t *pm);
- void psci_prepare_next_non_secure_ctx(entry_point_info_t *next_image_info);
-
-The CPU context data 'cpu_context_t' is programmed to the registers differently
-when PSCI is integrated with an AArch32 EL3 Runtime Software compared to
-when the PSCI is integrated with an AArch64 EL3 Runtime Software (BL31). For
-example, in the case of AArch64, there is no need to retrieve ``cpu_context_t``
-data and program the registers as it will done implicitly as part of
-``el3_exit``. The description below of the PSCI interfaces is targeted at
-integration with an AArch32 EL3 Runtime Software.
-
-The PSCI library is responsible for initializing/restoring the non-secure world
-to an appropriate state after boot and may choose to directly program the
-non-secure system registers. The PSCI generic code takes care not to directly
-modify any of the system registers affecting the secure world and instead
-returns the values to be programmed to these registers via ``cpu_context_t``.
-The EL3 Runtime Software is responsible for programming those registers and
-can use the proposed values provided in the ``cpu_context_t``, modifying the
-values if required.
-
-PSCI library needs the flexibility to access both secure and non-secure
-copies of banked registers. Hence it needs to be invoked in Monitor mode
-for AArch32 and in EL3 for AArch64. The NS bit in SCR (in AArch32) or SCR_EL3
-(in AArch64) must be set to 0. Additional requirements for the PSCI library
-interfaces are:
-
-- Instruction cache must be enabled
-- Both IRQ and FIQ must be masked for the current CPU
-- The page tables must be setup and the MMU enabled
-- The C runtime environment must be setup and stack initialized
-- The Data cache must be enabled prior to invoking any of the PSCI library
- interfaces except for ``psci_warmboot_entrypoint()``. For
- ``psci_warmboot_entrypoint()``, if the build option ``HW_ASSISTED_COHERENCY``
- is enabled however, data caches are expected to be enabled.
-
-Further requirements for each interface can be found in the interface
-description.
-
-Interface : psci_setup()
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : const psci_lib_args_t *lib_args
- Return : void
-
-This function is to be called by the primary CPU during cold boot before
-any other interface to the PSCI library. It takes ``lib_args``, a const pointer
-to ``psci_lib_args_t``, as the argument. The ``psci_lib_args_t`` is a versioned
-structure and is declared in ``psci_lib.h`` header as follows:
-
-.. code:: c
-
- typedef struct psci_lib_args {
- /* The version information of PSCI Library Interface */
- param_header_t h;
- /* The warm boot entrypoint function */
- mailbox_entrypoint_t mailbox_ep;
- } psci_lib_args_t;
-
-The first field ``h``, of ``param_header_t`` type, provides the version
-information. The second field ``mailbox_ep`` is the warm boot entrypoint address
-and is used to configure the platform mailbox. Helper macros are provided in
-``psci_lib.h`` to construct the ``lib_args`` argument statically or during
-runtime. Prior to calling the ``psci_setup()`` interface, the platform setup for
-cold boot must have completed. Major actions performed by this interface are:
-
-- Initializes architecture.
-- Initializes PSCI power domain and state coordination data structures.
-- Calls ``plat_setup_psci_ops()`` with warm boot entrypoint ``mailbox_ep`` as
- argument.
-- Calls ``cm_set_context_by_index()`` (see
- `CPU Context management API`_) for all the CPUs in the
- platform
-
-Interface : psci_prepare_next_non_secure_ctx()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : entry_point_info_t *next_image_info
- Return : void
-
-After ``psci_setup()`` and prior to exit to the non-secure world, this function
-must be called by the EL3 Runtime Software to initialize the non-secure world
-context. The non-secure world entrypoint information ``next_image_info`` (first
-argument) will be used to determine the non-secure context. After this function
-returns, the EL3 Runtime Software must retrieve the ``cpu_context_t`` (using
-cm_get_context()) for the current CPU and program the registers prior to exit
-to the non-secure world.
-
-Interface : psci_register_spd_pm_hook()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : const spd_pm_ops_t *
- Return : void
-
-As explained in `Secure payload power management callback`_,
-the EL3 Runtime Software may want to perform some bookkeeping during power
-management operations. This function is used to register the ``spd_pm_ops_t``
-(first argument) callbacks with the PSCI library which will be called
-appropriately during power management. Calling this function is optional and
-need to be called by the primary CPU during the cold boot sequence after
-``psci_setup()`` has completed.
-
-Interface : psci_smc_handler()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : uint32_t smc_fid, u_register_t x1,
- u_register_t x2, u_register_t x3,
- u_register_t x4, void *cookie,
- void *handle, u_register_t flags
- Return : u_register_t
-
-This function is the top level handler for SMCs which fall within the
-PSCI service range specified in `SMCCC`_. The function ID ``smc_fid`` (first
-argument) determines the PSCI API to be called. The ``x1`` to ``x4`` (2nd to 5th
-arguments), are the values of the registers r1 - r4 (in AArch32) or x1 - x4
-(in AArch64) when the SMC is received. These are the arguments to PSCI API as
-described in `PSCI spec`_. The 'flags' (8th argument) is a bit field parameter
-and is detailed in 'smccc.h' header. It includes whether the call is from the
-secure or non-secure world. The ``cookie`` (6th argument) and the ``handle``
-(7th argument) are not used and are reserved for future use.
-
-The return value from this interface is the return value from the underlying
-PSCI API corresponding to ``smc_fid``. This function may not return back to the
-caller if PSCI API causes power down of the CPU. In this case, when the CPU
-wakes up, it will start execution from the warm reset address.
-
-Interface : psci_warmboot_entrypoint()
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-::
-
- Argument : void
- Return : void
-
-This function performs the warm boot initialization/restoration as mandated by
-`PSCI spec`_. For AArch32, on wakeup from power down the CPU resets to secure SVC
-mode and the EL3 Runtime Software must perform the prerequisite initializations
-mentioned at top of this section. This function must be called with Data cache
-disabled (unless build option ``HW_ASSISTED_COHERENCY`` is enabled) but with MMU
-initialized and enabled. The major actions performed by this function are:
-
-- Invalidates the stack and enables the data cache.
-- Initializes architecture and PSCI state coordination.
-- Restores/Initializes the peripheral drivers to the required state via
- appropriate ``plat_psci_ops_t`` hooks
-- Restores the EL3 Runtime Software context via appropriate ``spd_pm_ops_t``
- callbacks.
-- Restores/Initializes the non-secure context and populates the
- ``cpu_context_t`` for the current CPU.
-
-Upon the return of this function, the EL3 Runtime Software must retrieve the
-non-secure ``cpu_context_t`` using ``cm_get_context()`` and program the registers
-prior to exit to the non-secure world.
-
-EL3 Runtime Software dependencies
----------------------------------
-
-The PSCI Library includes supporting frameworks like context management,
-cpu operations (cpu_ops) and per-cpu data framework. Other helper library
-functions like bakery locks and spin locks are also included in the library.
-The dependencies which must be fulfilled by the EL3 Runtime Software
-for integration with PSCI library are described below.
-
-General dependencies
-~~~~~~~~~~~~~~~~~~~~
-
-The PSCI library being a Multiprocessor (MP) implementation, EL3 Runtime
-Software must provide an SMC handling framework capable of MP adhering to
-`SMCCC`_ specification.
-
-The EL3 Runtime Software must also export cache maintenance primitives
-and some helper utilities for assert, print and memory operations as listed
-below. The TF-A source tree provides implementations for all
-these functions but the EL3 Runtime Software may use its own implementation.
-
-**Functions : assert(), memcpy(), memset(), printf()**
-
-These must be implemented as described in ISO C Standard.
-
-**Function : flush_dcache_range()**
-
-::
-
- Argument : uintptr_t addr, size_t size
- Return : void
-
-This function cleans and invalidates (flushes) the data cache for memory
-at address ``addr`` (first argument) address and of size ``size`` (second argument).
-
-**Function : inv_dcache_range()**
-
-::
-
- Argument : uintptr_t addr, size_t size
- Return : void
-
-This function invalidates (flushes) the data cache for memory at address
-``addr`` (first argument) address and of size ``size`` (second argument).
-
-**Function : do_panic()**
-
-::
-
- Argument : void
- Return : void
-
-This function will be called by the PSCI library on encountering a critical
-failure that cannot be recovered from. This function **must not** return.
-
-CPU Context management API
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The CPU context management data memory is statically allocated by PSCI library
-in BSS section. The PSCI library requires the EL3 Runtime Software to implement
-APIs to store and retrieve pointers to this CPU context data. SP-MIN
-demonstrates how these APIs can be implemented but the EL3 Runtime Software can
-choose a more optimal implementation (like dedicating the secure TPIDRPRW
-system register (in AArch32) for storing these pointers).
-
-**Function : cm_set_context_by_index()**
-
-::
-
- Argument : unsigned int cpu_idx, void *context, unsigned int security_state
- Return : void
-
-This function is called during cold boot when the ``psci_setup()`` PSCI library
-interface is called.
-
-This function must store the pointer to the CPU context data, ``context`` (2nd
-argument), for the specified ``security_state`` (3rd argument) and CPU identified
-by ``cpu_idx`` (first argument). The ``security_state`` will always be non-secure
-when called by PSCI library and this argument is retained for compatibility
-with BL31. The ``cpu_idx`` will correspond to the index returned by the
-``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU.
-
-The actual method of storing the ``context`` pointers is implementation specific.
-For example, SP-MIN stores the pointers in the array ``sp_min_cpu_ctx_ptr``
-declared in ``sp_min_main.c``.
-
-**Function : cm_get_context()**
-
-::
-
- Argument : uint32_t security_state
- Return : void *
-
-This function must return the pointer to the ``cpu_context_t`` structure for
-the specified ``security_state`` (first argument) for the current CPU. The caller
-must ensure that ``cm_set_context_by_index`` is called first and the appropriate
-context pointers are stored prior to invoking this API. The ``security_state``
-will always be non-secure when called by PSCI library and this argument
-is retained for compatibility with BL31.
-
-**Function : cm_get_context_by_index()**
-
-::
-
- Argument : unsigned int cpu_idx, unsigned int security_state
- Return : void *
-
-This function must return the pointer to the ``cpu_context_t`` structure for
-the specified ``security_state`` (second argument) for the CPU identified by
-``cpu_idx`` (first argument). The caller must ensure that
-``cm_set_context_by_index`` is called first and the appropriate context
-pointers are stored prior to invoking this API. The ``security_state`` will
-always be non-secure when called by PSCI library and this argument is
-retained for compatibility with BL31. The ``cpu_idx`` will correspond to the
-index returned by the ``plat_core_pos_by_mpidr()`` for ``mpidr`` of the CPU.
-
-Platform API
-~~~~~~~~~~~~
-
-The platform layer abstracts the platform-specific details from the generic
-PSCI library. The following platform APIs/macros must be defined by the EL3
-Runtime Software for integration with the PSCI library.
-
-The mandatory platform APIs are:
-
-- plat_my_core_pos
-- plat_core_pos_by_mpidr
-- plat_get_syscnt_freq2
-- plat_get_power_domain_tree_desc
-- plat_setup_psci_ops
-- plat_reset_handler
-- plat_panic_handler
-- plat_get_my_stack
-
-The mandatory platform macros are:
-
-- PLATFORM_CORE_COUNT
-- PLAT_MAX_PWR_LVL
-- PLAT_NUM_PWR_DOMAINS
-- CACHE_WRITEBACK_GRANULE
-- PLAT_MAX_OFF_STATE
-- PLAT_MAX_RET_STATE
-- PLAT_MAX_PWR_LVL_STATES (optional)
-- PLAT_PCPU_DATA_SIZE (optional)
-
-The details of these APIs/macros can be found in `Porting Guide`_.
-
-All platform specific operations for power management are done via
-``plat_psci_ops_t`` callbacks registered by the platform when
-``plat_setup_psci_ops()`` API is called. The description of each of
-the callbacks in ``plat_psci_ops_t`` can be found in PSCI section of the
-`Porting Guide`_. If any these callbacks are not registered, then the
-PSCI API associated with that callback will not be supported by PSCI
-library.
-
-Secure payload power management callback
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-During PSCI power management operations, the EL3 Runtime Software may
-need to perform some bookkeeping, and PSCI library provides
-``spd_pm_ops_t`` callbacks for this purpose. These hooks must be
-populated and registered by using ``psci_register_spd_pm_hook()`` PSCI
-library interface.
-
-Typical bookkeeping during PSCI power management calls include save/restore
-of the EL3 Runtime Software context. Also if the EL3 Runtime Software makes
-use of secure interrupts, then these interrupts must also be managed
-appropriately during CPU power down/power up. Any secure interrupt targeted
-to the current CPU must be disabled or re-targeted to other running CPU prior
-to power down of the current CPU. During power up, these interrupt can be
-enabled/re-targeted back to the current CPU.
-
-.. code:: c
-
- typedef struct spd_pm_ops {
- void (*svc_on)(u_register_t target_cpu);
- int32_t (*svc_off)(u_register_t __unused);
- void (*svc_suspend)(u_register_t max_off_pwrlvl);
- void (*svc_on_finish)(u_register_t __unused);
- void (*svc_suspend_finish)(u_register_t max_off_pwrlvl);
- int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu);
- int32_t (*svc_migrate_info)(u_register_t *resident_cpu);
- void (*svc_system_off)(void);
- void (*svc_system_reset)(void);
- } spd_pm_ops_t;
-
-A brief description of each callback is given below:
-
-- svc_on, svc_off, svc_on_finish
-
- The ``svc_on``, ``svc_off`` callbacks are called during PSCI_CPU_ON,
- PSCI_CPU_OFF APIs respectively. The ``svc_on_finish`` is called when the
- target CPU of PSCI_CPU_ON API powers up and executes the
- ``psci_warmboot_entrypoint()`` PSCI library interface.
-
-- svc_suspend, svc_suspend_finish
-
- The ``svc_suspend`` callback is called during power down bu either
- PSCI_SUSPEND or PSCI_SYSTEM_SUSPEND APIs. The ``svc_suspend_finish`` is
- called when the CPU wakes up from suspend and executes the
- ``psci_warmboot_entrypoint()`` PSCI library interface. The ``max_off_pwrlvl``
- (first parameter) denotes the highest power domain level being powered down
- to or woken up from suspend.
-
-- svc_system_off, svc_system_reset
-
- These callbacks are called during PSCI_SYSTEM_OFF and PSCI_SYSTEM_RESET
- PSCI APIs respectively.
-
-- svc_migrate_info
-
- This callback is called in response to PSCI_MIGRATE_INFO_TYPE or
- PSCI_MIGRATE_INFO_UP_CPU APIs. The return value of this callback must
- correspond to the return value of PSCI_MIGRATE_INFO_TYPE API as described
- in `PSCI spec`_. If the secure payload is a Uniprocessor (UP)
- implementation, then it must update the mpidr of the CPU it is resident in
- via ``resident_cpu`` (first argument). The updates to ``resident_cpu`` is
- ignored if the secure payload is a multiprocessor (MP) implementation.
-
-- svc_migrate
-
- This callback is only relevant if the secure payload in EL3 Runtime
- Software is a Uniprocessor (UP) implementation and supports migration from
- the current CPU ``from_cpu`` (first argument) to another CPU ``to_cpu``
- (second argument). This callback is called in response to PSCI_MIGRATE
- API. This callback is never called if the secure payload is a
- Multiprocessor (MP) implementation.
-
-CPU operations
-~~~~~~~~~~~~~~
-
-The CPU operations (cpu_ops) framework implement power down sequence specific
-to the CPU and the details of which can be found in the
-``CPU specific operations framework`` section of `Firmware Design`_. The TF-A
-tree implements the ``cpu_ops`` for various supported CPUs and the EL3 Runtime
-Software needs to include the required ``cpu_ops`` in its build. The start and
-end of the ``cpu_ops`` descriptors must be exported by the EL3 Runtime Software
-via the ``__CPU_OPS_START__`` and ``__CPU_OPS_END__`` linker symbols.
-
-The ``cpu_ops`` descriptors also include reset sequences and may include errata
-workarounds for the CPU. The EL3 Runtime Software can choose to call this
-during cold/warm reset if it does not implement its own reset sequence/errata
-workarounds.
-
---------------
-
-*Copyright (c) 2016-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _PSCI spec: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
-.. _SMCCC: https://silver.arm.com/download/ARM_and_AMBA_Architecture/AR570-DA-80002-r0p0-00rel0/ARM_DEN0028A_SMC_Calling_Convention.pdf
-.. _PSCI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
-.. _PSCI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
-.. _Porting Guide: porting-guide.rst
-.. _Firmware Design: ./firmware-design.rst
+++ /dev/null
-PSCI Power Domain Tree design
-=============================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
---------------
-
-Requirements
-------------
-
-#. A platform must export the ``plat_get_aff_count()`` and
- ``plat_get_aff_state()`` APIs to enable the generic PSCI code to
- populate a tree that describes the hierarchy of power domains in the
- system. This approach is inflexible because a change to the topology
- requires a change in the code.
-
- It would be much simpler for the platform to describe its power domain tree
- in a data structure.
-
-#. The generic PSCI code generates MPIDRs in order to populate the power domain
- tree. It also uses an MPIDR to find a node in the tree. The assumption that
- a platform will use exactly the same MPIDRs as generated by the generic PSCI
- code is not scalable. The use of an MPIDR also restricts the number of
- levels in the power domain tree to four.
-
- Therefore, there is a need to decouple allocation of MPIDRs from the
- mechanism used to populate the power domain topology tree.
-
-#. The current arrangement of the power domain tree requires a binary search
- over the sibling nodes at a particular level to find a specified power
- domain node. During a power management operation, the tree is traversed from
- a 'start' to an 'end' power level. The binary search is required to find the
- node at each level. The natural way to perform this traversal is to
- start from a leaf node and follow the parent node pointer to reach the end
- level.
-
- Therefore, there is a need to define data structures that implement the tree in
- a way which facilitates such a traversal.
-
-#. The attributes of a core power domain differ from the attributes of power
- domains at higher levels. For example, only a core power domain can be identified
- using an MPIDR. There is no requirement to perform state coordination while
- performing a power management operation on the core power domain.
-
- Therefore, there is a need to implement the tree in a way which facilitates this
- distinction between a leaf and non-leaf node and any associated
- optimizations.
-
---------------
-
-Design
-------
-
-Describing a power domain tree
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To fulfill requirement 1., the existing platform APIs
-``plat_get_aff_count()`` and ``plat_get_aff_state()`` have been
-removed. A platform must define an array of unsigned chars such that:
-
-#. The first entry in the array specifies the number of power domains at the
- highest power level implemented in the platform. This caters for platforms
- where the power domain tree does not have a single root node, for example,
- the FVP has two cluster power domains at the highest level (1).
-
-#. Each subsequent entry corresponds to a power domain and contains the number
- of power domains that are its direct children.
-
-#. The size of the array minus the first entry will be equal to the number of
- non-leaf power domains.
-
-#. The value in each entry in the array is used to find the number of entries
- to consider at the next level. The sum of the values (number of children) of
- all the entries at a level specifies the number of entries in the array for
- the next level.
-
-The following example power domain topology tree will be used to describe the
-above text further. The leaf and non-leaf nodes in this tree have been numbered
-separately.
-
-::
-
- +-+
- |0|
- +-+
- / \
- / \
- / \
- / \
- / \
- / \
- / \
- / \
- / \
- / \
- +-+ +-+
- |1| |2|
- +-+ +-+
- / \ / \
- / \ / \
- / \ / \
- / \ / \
- +-+ +-+ +-+ +-+
- |3| |4| |5| |6|
- +-+ +-+ +-+ +-+
- +---+-----+ +----+----| +----+----+ +----+-----+-----+
- | | | | | | | | | | | | |
- | | | | | | | | | | | | |
- v v v v v v v v v v v v v
- +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +--+ +--+ +--+
- |0| |1| |2| |3| |4| |5| |6| |7| |8| |9| |10| |11| |12|
- +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +--+ +--+ +--+
-
-This tree is defined by the platform as the array described above as follows:
-
-::
-
- #define PLAT_NUM_POWER_DOMAINS 20
- #define PLATFORM_CORE_COUNT 13
- #define PSCI_NUM_NON_CPU_PWR_DOMAINS \
- (PLAT_NUM_POWER_DOMAINS - PLATFORM_CORE_COUNT)
-
- unsigned char plat_power_domain_tree_desc[] = { 1, 2, 2, 2, 3, 3, 3, 4};
-
-Removing assumptions about MPIDRs used in a platform
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To fulfill requirement 2., it is assumed that the platform assigns a
-unique number (core index) between ``0`` and ``PLAT_CORE_COUNT - 1`` to each core
-power domain. MPIDRs could be allocated in any manner and will not be used to
-populate the tree.
-
-``plat_core_pos_by_mpidr(mpidr)`` will return the core index for the core
-corresponding to the MPIDR. It will return an error (-1) if an MPIDR is passed
-which is not allocated or corresponds to an absent core. The semantics of this
-platform API have changed since it is required to validate the passed MPIDR. It
-has been made a mandatory API as a result.
-
-Another mandatory API, ``plat_my_core_pos()`` has been added to return the core
-index for the calling core. This API provides a more lightweight mechanism to get
-the index since there is no need to validate the MPIDR of the calling core.
-
-The platform should assign the core indices (as illustrated in the diagram above)
-such that, if the core nodes are numbered from left to right, then the index
-for a core domain will be the same as the index returned by
-``plat_core_pos_by_mpidr()`` or ``plat_my_core_pos()`` for that core. This
-relationship allows the core nodes to be allocated in a separate array
-(requirement 4.) during ``psci_setup()`` in such an order that the index of the
-core in the array is the same as the return value from these APIs.
-
-Dealing with holes in MPIDR allocation
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-For platforms where the number of allocated MPIDRs is equal to the number of
-core power domains, for example, Juno and FVPs, the logic to convert an MPIDR to
-a core index should remain unchanged. Both Juno and FVP use a simple collision
-proof hash function to do this.
-
-It is possible that on some platforms, the allocation of MPIDRs is not
-contiguous or certain cores have been disabled. This essentially means that the
-MPIDRs have been sparsely allocated, that is, the size of the range of MPIDRs
-used by the platform is not equal to the number of core power domains.
-
-The platform could adopt one of the following approaches to deal with this
-scenario:
-
-#. Implement more complex logic to convert a valid MPIDR to a core index while
- maintaining the relationship described earlier. This means that the power
- domain tree descriptor will not describe any core power domains which are
- disabled or absent. Entries will not be allocated in the tree for these
- domains.
-
-#. Treat unallocated MPIDRs and disabled cores as absent but still describe them
- in the power domain descriptor, that is, the number of core nodes described
- is equal to the size of the range of MPIDRs allocated. This approach will
- lead to memory wastage since entries will be allocated in the tree but will
- allow use of a simpler logic to convert an MPIDR to a core index.
-
-Traversing through and distinguishing between core and non-core power domains
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To fulfill requirement 3 and 4, separate data structures have been defined
-to represent leaf and non-leaf power domain nodes in the tree.
-
-.. code:: c
-
- /*******************************************************************************
- * The following two data structures implement the power domain tree. The tree
- * is used to track the state of all the nodes i.e. power domain instances
- * described by the platform. The tree consists of nodes that describe CPU power
- * domains i.e. leaf nodes and all other power domains which are parents of a
- * CPU power domain i.e. non-leaf nodes.
- ******************************************************************************/
- typedef struct non_cpu_pwr_domain_node {
- /*
- * Index of the first CPU power domain node level 0 which has this node
- * as its parent.
- */
- unsigned int cpu_start_idx;
-
- /*
- * Number of CPU power domains which are siblings of the domain indexed
- * by 'cpu_start_idx' i.e. all the domains in the range 'cpu_start_idx
- * -> cpu_start_idx + ncpus' have this node as their parent.
- */
- unsigned int ncpus;
-
- /* Index of the parent power domain node */
- unsigned int parent_node;
-
- -----
- } non_cpu_pd_node_t;
-
- typedef struct cpu_pwr_domain_node {
- u_register_t mpidr;
-
- /* Index of the parent power domain node */
- unsigned int parent_node;
-
- -----
- } cpu_pd_node_t;
-
-The power domain tree is implemented as a combination of the following data
-structures.
-
-::
-
- non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS];
- cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
-
-Populating the power domain tree
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``populate_power_domain_tree()`` function in ``psci_setup.c`` implements the
-algorithm to parse the power domain descriptor exported by the platform to
-populate the two arrays. It is essentially a breadth-first-search. The nodes for
-each level starting from the root are laid out one after another in the
-``psci_non_cpu_pd_nodes`` and ``psci_cpu_pd_nodes`` arrays as follows:
-
-::
-
- psci_non_cpu_pd_nodes -> [[Level 3 nodes][Level 2 nodes][Level 1 nodes]]
- psci_cpu_pd_nodes -> [Level 0 nodes]
-
-For the example power domain tree illustrated above, the ``psci_cpu_pd_nodes``
-will be populated as follows. The value in each entry is the index of the parent
-node. Other fields have been ignored for simplicity.
-
-::
-
- +-------------+ ^
- CPU0 | 3 | |
- +-------------+ |
- CPU1 | 3 | |
- +-------------+ |
- CPU2 | 3 | |
- +-------------+ |
- CPU3 | 4 | |
- +-------------+ |
- CPU4 | 4 | |
- +-------------+ |
- CPU5 | 4 | | PLATFORM_CORE_COUNT
- +-------------+ |
- CPU6 | 5 | |
- +-------------+ |
- CPU7 | 5 | |
- +-------------+ |
- CPU8 | 5 | |
- +-------------+ |
- CPU9 | 6 | |
- +-------------+ |
- CPU10 | 6 | |
- +-------------+ |
- CPU11 | 6 | |
- +-------------+ |
- CPU12 | 6 | v
- +-------------+
-
-The ``psci_non_cpu_pd_nodes`` array will be populated as follows. The value in
-each entry is the index of the parent node.
-
-::
-
- +-------------+ ^
- PD0 | -1 | |
- +-------------+ |
- PD1 | 0 | |
- +-------------+ |
- PD2 | 0 | |
- +-------------+ |
- PD3 | 1 | | PLAT_NUM_POWER_DOMAINS -
- +-------------+ | PLATFORM_CORE_COUNT
- PD4 | 1 | |
- +-------------+ |
- PD5 | 2 | |
- +-------------+ |
- PD6 | 2 | |
- +-------------+ v
-
-Each core can find its node in the ``psci_cpu_pd_nodes`` array using the
-``plat_my_core_pos()`` function. When a core is turned on, the normal world
-provides an MPIDR. The ``plat_core_pos_by_mpidr()`` function is used to validate
-the MPIDR before using it to find the corresponding core node. The non-core power
-domain nodes do not need to be identified.
-
---------------
-
-*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
+++ /dev/null
-PSCI Performance Measurements on Arm Juno Development Platform
-==============================================================
-
-This document summarises the findings of performance measurements of key
-operations in the ARM Trusted Firmware (TF) Power State Coordination Interface
-(PSCI) implementation, using the in-built Performance Measurement Framework
-(PMF) and runtime instrumentation timestamps.
-
-Method
-------
-
-We used the `Juno R1 platform`_ for these tests, which has 4 x Cortex-A53 and 2
-x Cortex-A57 clusters running at the following frequencies:
-
-+-----------------+--------------------+
-| Domain | Frequency (MHz) |
-+=================+====================+
-| Cortex-A57 | 900 (nominal) |
-+-----------------+--------------------+
-| Cortex-A53 | 650 (underdrive) |
-+-----------------+--------------------+
-| AXI subsystem | 533 |
-+-----------------+--------------------+
-
-Juno supports CPU, cluster and system power down states, corresponding to power
-levels 0, 1 and 2 respectively. It does not support any retention states.
-
-We used the upstream `TF master as of 31/01/2017`_, building the platform using
-the ``ENABLE_RUNTIME_INSTRUMENTATION`` option:
-
-::
-
- make PLAT=juno ENABLE_RUNTIME_INSTRUMENTATION=1 \
- SCP_BL2=<path/to/scp-fw.bin> \
- BL33=<path/to/test-fw.bin> \
- all fip
-
-When using the debug build of TF, there was no noticeable difference in the
-results.
-
-The tests are based on an ARM-internal test framework. The release build of this
-framework was used because the results in the debug build became skewed; the
-console output prevented some of the tests from executing in parallel.
-
-The tests consist of both parallel and sequential tests, which are broadly
-described as follows:
-
-- **Parallel Tests** This type of test powers on all the non-lead CPUs and
- brings them and the lead CPU to a common synchronization point. The lead CPU
- then initiates the test on all CPUs in parallel.
-
-- **Sequential Tests** This type of test powers on each non-lead CPU in
- sequence. The lead CPU initiates the test on a non-lead CPU then waits for the
- test to complete before proceeding to the next non-lead CPU. The lead CPU then
- executes the test on itself.
-
-In the results below, CPUs 0-3 refer to CPUs in the little cluster (A53) and
-CPUs 4-5 refer to CPUs in the big cluster (A57). In all cases CPU 4 is the lead
-CPU.
-
-``PSCI_ENTRY`` refers to the time taken from entering the TF PSCI implementation
-to the point the hardware enters the low power state (WFI). Referring to the TF
-runtime instrumentation points, this corresponds to:
-``(RT_INSTR_ENTER_HW_LOW_PWR - RT_INSTR_ENTER_PSCI)``.
-
-``PSCI_EXIT`` refers to the time taken from the point the hardware exits the low
-power state to exiting the TF PSCI implementation. This corresponds to:
-``(RT_INSTR_EXIT_PSCI - RT_INSTR_EXIT_HW_LOW_PWR)``.
-
-``CFLUSH_OVERHEAD`` refers to the part of ``PSCI_ENTRY`` taken to flush the
-caches. This corresponds to: ``(RT_INSTR_EXIT_CFLUSH - RT_INSTR_ENTER_CFLUSH)``.
-
-Note there is very little variance observed in the values given (~1us), although
-the values for each CPU are sometimes interchanged, depending on the order in
-which locks are acquired. Also, there is very little variance observed between
-executing the tests sequentially in a single boot or rebooting between tests.
-
-Given that runtime instrumentation using PMF is invasive, there is a small
-(unquantified) overhead on the results. PMF uses the generic counter for
-timestamps, which runs at 50MHz on Juno.
-
-Results and Commentary
-----------------------
-
-``CPU_SUSPEND`` to deepest power level on all CPUs in parallel
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------+---------------------+--------------------+--------------------------+
-| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
-+=======+=====================+====================+==========================+
-| 0 | 27 | 20 | 5 |
-+-------+---------------------+--------------------+--------------------------+
-| 1 | 114 | 86 | 5 |
-+-------+---------------------+--------------------+--------------------------+
-| 2 | 202 | 58 | 5 |
-+-------+---------------------+--------------------+--------------------------+
-| 3 | 375 | 29 | 94 |
-+-------+---------------------+--------------------+--------------------------+
-| 4 | 20 | 22 | 6 |
-+-------+---------------------+--------------------+--------------------------+
-| 5 | 290 | 18 | 206 |
-+-------+---------------------+--------------------+--------------------------+
-
-A large variance in ``PSCI_ENTRY`` and ``PSCI_EXIT`` times across CPUs is
-observed due to TF PSCI lock contention. In the worst case, CPU 3 has to wait
-for the 3 other CPUs in the cluster (0-2) to complete ``PSCI_ENTRY`` and release
-the lock before proceeding.
-
-The ``CFLUSH_OVERHEAD`` times for CPUs 3 and 5 are higher because they are the
-last CPUs in their respective clusters to power down, therefore both the L1 and
-L2 caches are flushed.
-
-The ``CFLUSH_OVERHEAD`` time for CPU 5 is a lot larger than that for CPU 3
-because the L2 cache size for the big cluster is lot larger (2MB) compared to
-the little cluster (1MB).
-
-``CPU_SUSPEND`` to power level 0 on all CPUs in parallel
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------+---------------------+--------------------+--------------------------+
-| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
-+=======+=====================+====================+==========================+
-| 0 | 116 | 14 | 8 |
-+-------+---------------------+--------------------+--------------------------+
-| 1 | 204 | 14 | 8 |
-+-------+---------------------+--------------------+--------------------------+
-| 2 | 287 | 13 | 8 |
-+-------+---------------------+--------------------+--------------------------+
-| 3 | 376 | 13 | 9 |
-+-------+---------------------+--------------------+--------------------------+
-| 4 | 29 | 15 | 7 |
-+-------+---------------------+--------------------+--------------------------+
-| 5 | 21 | 15 | 8 |
-+-------+---------------------+--------------------+--------------------------+
-
-There is no lock contention in TF generic code at power level 0 but the large
-variance in ``PSCI_ENTRY`` times across CPUs is due to lock contention in Juno
-platform code. The platform lock is used to mediate access to a single SCP
-communication channel. This is compounded by the SCP firmware waiting for each
-AP CPU to enter WFI before making the channel available to other CPUs, which
-effectively serializes the SCP power down commands from all CPUs.
-
-On platforms with a more efficient CPU power down mechanism, it should be
-possible to make the ``PSCI_ENTRY`` times smaller and consistent.
-
-The ``PSCI_EXIT`` times are consistent across all CPUs because TF does not
-require locks at power level 0.
-
-The ``CFLUSH_OVERHEAD`` times for all CPUs are small and consistent since only
-the cache associated with power level 0 is flushed (L1).
-
-``CPU_SUSPEND`` to deepest power level on all CPUs in sequence
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------+---------------------+--------------------+--------------------------+
-| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
-+=======+=====================+====================+==========================+
-| 0 | 114 | 20 | 94 |
-+-------+---------------------+--------------------+--------------------------+
-| 1 | 114 | 20 | 94 |
-+-------+---------------------+--------------------+--------------------------+
-| 2 | 114 | 20 | 94 |
-+-------+---------------------+--------------------+--------------------------+
-| 3 | 114 | 20 | 94 |
-+-------+---------------------+--------------------+--------------------------+
-| 4 | 195 | 22 | 180 |
-+-------+---------------------+--------------------+--------------------------+
-| 5 | 21 | 17 | 6 |
-+-------+---------------------+--------------------+--------------------------+
-
-The ``CLUSH_OVERHEAD`` times for lead CPU 4 and all CPUs in the non-lead cluster
-are large because all other CPUs in the cluster are powered down during the
-test. The ``CPU_SUSPEND`` call powers down to the cluster level, requiring a
-flush of both L1 and L2 caches.
-
-The ``CFLUSH_OVERHEAD`` time for CPU 4 is a lot larger than those for the little
-CPUs because the L2 cache size for the big cluster is lot larger (2MB) compared
-to the little cluster (1MB).
-
-The ``PSCI_ENTRY`` and ``CFLUSH_OVERHEAD`` times for CPU 5 are low because lead
-CPU 4 continues to run while CPU 5 is suspended. Hence CPU 5 only powers down to
-level 0, which only requires L1 cache flush.
-
-``CPU_SUSPEND`` to power level 0 on all CPUs in sequence
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-+-------+---------------------+--------------------+--------------------------+
-| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
-+=======+=====================+====================+==========================+
-| 0 | 22 | 14 | 5 |
-+-------+---------------------+--------------------+--------------------------+
-| 1 | 22 | 14 | 5 |
-+-------+---------------------+--------------------+--------------------------+
-| 2 | 21 | 14 | 5 |
-+-------+---------------------+--------------------+--------------------------+
-| 3 | 22 | 14 | 5 |
-+-------+---------------------+--------------------+--------------------------+
-| 4 | 17 | 14 | 6 |
-+-------+---------------------+--------------------+--------------------------+
-| 5 | 18 | 15 | 6 |
-+-------+---------------------+--------------------+--------------------------+
-
-Here the times are small and consistent since there is no contention and it is
-only necessary to flush the cache to power level 0 (L1). This is the best case
-scenario.
-
-The ``PSCI_ENTRY`` times for CPUs in the big cluster are slightly smaller than
-for the CPUs in little cluster due to greater CPU performance.
-
-The ``PSCI_EXIT`` times are generally lower than in the last test because the
-cluster remains powered on throughout the test and there is less code to execute
-on power on (for example, no need to enter CCI coherency)
-
-``CPU_OFF`` on all non-lead CPUs in sequence then ``CPU_SUSPEND`` on lead CPU to deepest power level
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The test sequence here is as follows:
-
-1. Call ``CPU_ON`` and ``CPU_OFF`` on each non-lead CPU in sequence.
-
-2. Program wake up timer and suspend the lead CPU to the deepest power level.
-
-3. Call ``CPU_ON`` on non-lead CPU to get the timestamps from each CPU.
-
-+-------+---------------------+--------------------+--------------------------+
-| CPU | ``PSCI_ENTRY`` (us) | ``PSCI_EXIT`` (us) | ``CFLUSH_OVERHEAD`` (us) |
-+=======+=====================+====================+==========================+
-| 0 | 110 | 28 | 93 |
-+-------+---------------------+--------------------+--------------------------+
-| 1 | 110 | 28 | 93 |
-+-------+---------------------+--------------------+--------------------------+
-| 2 | 110 | 28 | 93 |
-+-------+---------------------+--------------------+--------------------------+
-| 3 | 111 | 28 | 93 |
-+-------+---------------------+--------------------+--------------------------+
-| 4 | 195 | 22 | 181 |
-+-------+---------------------+--------------------+--------------------------+
-| 5 | 20 | 23 | 6 |
-+-------+---------------------+--------------------+--------------------------+
-
-The ``CFLUSH_OVERHEAD`` times for all little CPUs are large because all other
-CPUs in that cluster are powerered down during the test. The ``CPU_OFF`` call
-powers down to the cluster level, requiring a flush of both L1 and L2 caches.
-
-The ``PSCI_ENTRY`` and ``CFLUSH_OVERHEAD`` times for CPU 5 are small because
-lead CPU 4 is running and CPU 5 only powers down to level 0, which only requires
-an L1 cache flush.
-
-The ``CFLUSH_OVERHEAD`` time for CPU 4 is a lot larger than those for the little
-CPUs because the L2 cache size for the big cluster is lot larger (2MB) compared
-to the little cluster (1MB).
-
-The ``PSCI_EXIT`` times for CPUs in the big cluster are slightly smaller than
-for CPUs in the little cluster due to greater CPU performance. These times
-generally are greater than the ``PSCI_EXIT`` times in the ``CPU_SUSPEND`` tests
-because there is more code to execute in the "on finisher" compared to the
-"suspend finisher" (for example, GIC redistributor register programming).
-
-``PSCI_VERSION`` on all CPUs in parallel
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Since very little code is associated with ``PSCI_VERSION``, this test
-approximates the round trip latency for handling a fast SMC at EL3 in TF.
-
-+-------+-------------------+
-| CPU | TOTAL TIME (ns) |
-+=======+===================+
-| 0 | 3020 |
-+-------+-------------------+
-| 1 | 2940 |
-+-------+-------------------+
-| 2 | 2980 |
-+-------+-------------------+
-| 3 | 3060 |
-+-------+-------------------+
-| 4 | 520 |
-+-------+-------------------+
-| 5 | 720 |
-+-------+-------------------+
-
-The times for the big CPUs are less than the little CPUs due to greater CPU
-performance.
-
-We suspect the time for lead CPU 4 is shorter than CPU 5 due to subtle cache
-effects, given that these measurements are at the nano-second level.
-
-.. _Juno R1 platform: https://www.arm.com/files/pdf/Juno_r1_ARM_Dev_datasheet.pdf
-.. _TF master as of 31/01/2017: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/?id=c38b36d
+++ /dev/null
-RAS support in Trusted Firmware-A
-=================================
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
- :depth: 2
-
-.. |EHF| replace:: Exception Handling Framework
-.. |TF-A| replace:: Trusted Firmware-A
-
-This document describes |TF-A| support for Arm Reliability, Availability, and
-Serviceability (RAS) extensions. RAS is a mandatory extension for Armv8.2 and
-later CPUs, and also an optional extension to the base Armv8.0 architecture.
-
-In conjunction with the |EHF|, support for RAS extension enables firmware-first
-paradigm for handling platform errors: exceptions resulting from errors are
-routed to and handled in EL3. Said errors are Synchronous External Abort (SEA),
-Asynchronous External Abort (signalled as SErrors), Fault Handling and Error
-Recovery interrupts. The |EHF| document mentions various `error handling
-use-cases`__.
-
-.. __: exception-handling.rst#delegation-use-cases
-
-For the description of Arm RAS extensions, Standard Error Records, and the
-precise definition of RAS terminology, please refer to the Arm Architecture
-Reference Manual. The rest of this document assumes familiarity with
-architecture and terminology.
-
-Overview
---------
-
-As mentioned above, the RAS support in |TF-A| enables routing to and handling of
-exceptions resulting from platform errors in EL3. It allows the platform to
-define an External Abort handler, and to register RAS nodes and interrupts. RAS
-framework also provides `helpers`__ for accessing Standard Error Records as
-introduced by the RAS extensions.
-
-.. __: `Standard Error Record helpers`_
-
-The build option ``RAS_EXTENSION`` when set to ``1`` includes the RAS in run
-time firmware; ``EL3_EXCEPTION_HANDLING`` and ``HANDLE_EA_EL3_FIRST`` must also
-be set ``1``.
-
-.. _ras-figure:
-
-.. image:: draw.io/ras.svg
-
-See more on `Engaging the RAS framework`_.
-
-Platform APIs
--------------
-
-The RAS framework allows the platform to define handlers for External Abort,
-Uncontainable Errors, Double Fault, and errors rising from EL3 execution. Please
-refer to the porting guide for the `RAS platform API descriptions`__.
-
-.. __: porting-guide.rst#external-abort-handling-and-ras-support
-
-Registering RAS error records
------------------------------
-
-RAS nodes are components in the system capable of signalling errors to PEs
-through one one of the notification mechanisms—SEAs, SErrors, or interrupts. RAS
-nodes contain one or more error records, which are registers through which the
-nodes advertise various properties of the signalled error. Arm recommends that
-error records are implemented in the Standard Error Record format. The RAS
-architecture allows for error records to be accessible via system or
-memory-mapped registers.
-
-The platform should enumerate the error records providing for each of them:
-
-- A handler to probe error records for errors;
-- When the probing identifies an error, a handler to handle it;
-- For memory-mapped error record, its base address and size in KB; for a system
- register-accessed record, the start index of the record and number of
- continuous records from that index;
-- Any node-specific auxiliary data.
-
-With this information supplied, when the run time firmware receives one of the
-notification mechanisms, the RAS framework can iterate through and probe error
-records for error, and invoke the appropriate handler to handle it.
-
-The RAS framework provides the macros to populate error record information. The
-macros are versioned, and the latest version as of this writing is 1. These
-macros create a structure of type ``struct err_record_info`` from its arguments,
-which are later passed to probe and error handlers.
-
-For memory-mapped error records:
-
-.. code:: c
-
- ERR_RECORD_MEMMAP_V1(base_addr, size_num_k, probe, handler, aux)
-
-And, for system register ones:
-
-.. code:: c
-
- ERR_RECORD_SYSREG_V1(idx_start, num_idx, probe, handler, aux)
-
-The probe handler must have the following prototype:
-
-.. code:: c
-
- typedef int (*err_record_probe_t)(const struct err_record_info *info,
- int *probe_data);
-
-The probe handler must return a non-zero value if an error was detected, or 0
-otherwise. The ``probe_data`` output parameter can be used to pass any useful
-information resulting from probe to the error handler (see `below`__). For
-example, it could return the index of the record.
-
-.. __: `Standard Error Record helpers`_
-
-The error handler must have the following prototype:
-
-.. code:: c
-
- typedef int (*err_record_handler_t)(const struct err_record_info *info,
- int probe_data, const struct err_handler_data *const data);
-
-The ``data`` constant parameter describes the various properties of the error,
-including the reason for the error, exception syndrome, and also ``flags``,
-``cookie``, and ``handle`` parameters from the `top-level exception handler`__.
-
-.. __: interrupt-framework-design.rst#el3-interrupts
-
-The platform is expected populate an array using the macros above, and register
-the it with the RAS framework using the macro ``REGISTER_ERR_RECORD_INFO()``,
-passing it the name of the array describing the records. Note that the macro
-must be used in the same file where the array is defined.
-
-Standard Error Record helpers
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The |TF-A| RAS framework provides probe handlers for Standard Error Records, for
-both memory-mapped and System Register accesses:
-
-.. code:: c
-
- int ras_err_ser_probe_memmap(const struct err_record_info *info,
- int *probe_data);
-
- int ras_err_ser_probe_sysreg(const struct err_record_info *info,
- int *probe_data);
-
-When the platform enumerates error records, for those records in the Standard
-Error Record format, these helpers maybe used instead of rolling out their own.
-Both helpers above:
-
-- Return non-zero value when an error is detected in a Standard Error Record;
-- Set ``probe_data`` to the index of the error record upon detecting an error.
-
-Registering RAS interrupts
---------------------------
-
-RAS nodes can signal errors to the PE by raising Fault Handling and/or Error
-Recovery interrupts. For the firmware-first handling paradigm for interrupts to
-work, the platform must setup and register with |EHF|. See `Interaction with
-Exception Handling Framework`_.
-
-For each RAS interrupt, the platform has to provide structure of type ``struct
-ras_interrupt``:
-
-- Interrupt number;
-- The associated error record information (pointer to the corresponding
- ``struct err_record_info``);
-- Optionally, a cookie.
-
-The platform is expected to define an array of ``struct ras_interrupt``, and
-register it with the RAS framework using the macro
-``REGISTER_RAS_INTERRUPTS()``, passing it the name of the array. Note that the
-macro must be used in the same file where the array is defined.
-
-The array of ``struct ras_interrupt`` must be sorted in the increasing order of
-interrupt number. This allows for fast look of handlers in order to service RAS
-interrupts.
-
-Double-fault handling
----------------------
-
-A Double Fault condition arises when an error is signalled to the PE while
-handling of a previously signalled error is still underway. When a Double Fault
-condition arises, the Arm RAS extensions only require for handler to perform
-orderly shutdown of the system, as recovery may be impossible.
-
-The RAS extensions part of Armv8.4 introduced new architectural features to deal
-with Double Fault conditions, specifically, the introduction of ``NMEA`` and
-``EASE`` bits to ``SCR_EL3`` register. These were introduced to assist EL3
-software which runs part of its entry/exit routines with exceptions momentarily
-masked—meaning, in such systems, External Aborts/SErrors are not immediately
-handled when they occur, but only after the exceptions are unmasked again.
-
-|TF-A|, for legacy reasons, executes entire EL3 with all exceptions unmasked.
-This means that all exceptions routed to EL3 are handled immediately. |TF-A|
-thus is able to detect a Double Fault conditions in software, without needing
-the intended advantages of Armv8.4 Double Fault architecture extensions.
-
-Double faults are fatal, and terminate at the platform double fault handler, and
-doesn't return.
-
-Engaging the RAS framework
---------------------------
-
-Enabling RAS support is a platform choice constructed from three distinct, but
-related, build options:
-
-- ``RAS_EXTENSION=1`` includes the RAS framework in the run time firmware;
-
-- ``EL3_EXCEPTION_HANDLING=1`` enables handling of exceptions at EL3. See
- `Interaction with Exception Handling Framework`_;
-
-- ``HANDLE_EA_EL3_FIRST=1`` enables routing of External Aborts and SErrors to
- EL3.
-
-The RAS support in |TF-A| introduces a default implementation of
-``plat_ea_handler``, the External Abort handler in EL3. When ``RAS_EXTENSION``
-is set to ``1``, it'll first call ``ras_ea_handler()`` function, which is the
-top-level RAS exception handler. ``ras_ea_handler`` is responsible for iterating
-to through platform-supplied error records, probe them, and when an error is
-identified, look up and invoke the corresponding error handler.
-
-Note that, if the platform chooses to override the ``plat_ea_handler`` function
-and intend to use the RAS framework, it must explicitly call
-``ras_ea_handler()`` from within.
-
-Similarly, for RAS interrupts, the framework defines
-``ras_interrupt_handler()``. The RAS framework arranges for it to be invoked
-when a RAS interrupt taken at EL3. The function bisects the platform-supplied
-sorted array of interrupts to look up the error record information associated
-with the interrupt number. That error handler for that record is then invoked to
-handle the error.
-
-Interaction with Exception Handling Framework
----------------------------------------------
-
-As mentioned in earlier sections, RAS framework interacts with the |EHF| to
-arbitrate handling of RAS exceptions with others that are routed to EL3. This
-means that the platform must partition a `priority level`__ for handling RAS
-exceptions. The platform must then define the macro ``PLAT_RAS_PRI`` to the
-priority level used for RAS exceptions. Platforms would typically want to
-allocate the highest secure priority for RAS handling.
-
-.. __: exception-handling.rst#partitioning-priority-levels
-
-Handling of both `interrupt`__ and `non-interrupt`__ exceptions follow the
-sequences outlined in the |EHF| documentation. I.e., for interrupts, the
-priority management is implicit; but for non-interrupt exceptions, they're
-explicit using `EHF APIs`__.
-
-.. __: exception-handling.rst#interrupt-flow
-.. __: exception-handling.rst#non-interrupt-flow
-.. __: exception-handling.rst#activating-and-deactivating-priorities
-
-----
-
-*Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.*
--- /dev/null
+Trusted Firmware-A - version 2.1
+================================
+
+.. section-numbering::
+ :suffix: .
+
+.. contents::
+
+Trusted Firmware-A (TF-A) provides a reference implementation of secure world
+software for `Armv7-A and Armv8-A`_, including a `Secure Monitor`_ executing
+at Exception Level 3 (EL3). It implements various Arm interface standards,
+such as:
+
+- The `Power State Coordination Interface (PSCI)`_
+- `Trusted Board Boot Requirements CLIENT (TBBR-CLIENT)`_
+- `SMC Calling Convention`_
+- `System Control and Management Interface (SCMI)`_
+- `Software Delegated Exception Interface (SDEI)`_
+
+Where possible, the code is designed for reuse or porting to other Armv7-A and
+Armv8-A model and hardware platforms.
+
+This release provides a suitable starting point for productization of secure
+world boot and runtime firmware, in either the AArch32 or AArch64 execution
+states.
+
+Users are encouraged to do their own security validation, including penetration
+testing, on any secure world code derived from TF-A.
+
+Arm will continue development in collaboration with interested parties to
+provide a full reference implementation of Secure Monitor code and Arm standards
+to the benefit of all developers working with Armv7-A and Armv8-A TrustZone
+technology.
+
+Documentation contents
+----------------------
+
+The `Trusted Firmware-A Documentation Contents`_ page contains an overview of
+the documentation that is available, with links to facilitate easier browsing.
+
+License
+-------
+
+The software is provided under a BSD-3-Clause `license`_. Contributions to this
+project are accepted under the same license with developer sign-off as
+described in the `Contributing Guidelines`_.
+
+This project contains code from other projects as listed below. The original
+license text is included in those source files.
+
+- The libc source code is derived from `FreeBSD`_ and `SCC`_. FreeBSD uses
+ various BSD licenses, including BSD-3-Clause and BSD-2-Clause. The SCC code
+ is used under the BSD-3-Clause license with the author's permission.
+
+- The libfdt source code is disjunctively dual licensed
+ (GPL-2.0+ OR BSD-2-Clause). It is used by this project under the terms of
+ the BSD-2-Clause license. Any contributions to this code must be made under
+ the terms of both licenses.
+
+- The LLVM compiler-rt source code is disjunctively dual licensed
+ (NCSA OR MIT). It is used by this project under the terms of the NCSA
+ license (also known as the University of Illinois/NCSA Open Source License),
+ which is a permissive license compatible with BSD-3-Clause. Any
+ contributions to this code must be made under the terms of both licenses.
+
+- The zlib source code is licensed under the Zlib license, which is a
+ permissive license compatible with BSD-3-Clause.
+
+- Some STMicroelectronics platform source code is disjunctively dual licensed
+ (GPL-2.0+ OR BSD-3-Clause). It is used by this project under the terms of the
+ BSD-3-Clause license. Any contributions to this code must be made under the
+ terms of both licenses.
+
+Functionality
+-------------
+
+- Initialization of the secure world, for example exception vectors, control
+ registers and interrupts for the platform.
+
+- Library support for CPU specific reset and power down sequences. This
+ includes support for errata workarounds and the latest Arm DynamIQ CPUs.
+
+- Drivers to enable standard initialization of Arm System IP, for example
+ Generic Interrupt Controller (GIC), Cache Coherent Interconnect (CCI),
+ Cache Coherent Network (CCN), Network Interconnect (NIC) and TrustZone
+ Controller (TZC).
+
+- A generic `SCMI`_ driver to interface with conforming power controllers, for
+ example the Arm System Control Processor (SCP).
+
+- SMC (Secure Monitor Call) handling, conforming to the `SMC Calling
+ Convention`_ using an EL3 runtime services framework.
+
+- `PSCI`_ library support for CPU, cluster and system power management
+ use-cases.
+ This library is pre-integrated with the AArch64 EL3 Runtime Software, and
+ is also suitable for integration with other AArch32 EL3 Runtime Software,
+ for example an AArch32 Secure OS.
+
+- A minimal AArch32 Secure Payload (SP\_MIN) to demonstrate `PSCI`_ library
+ integration with AArch32 EL3 Runtime Software.
+
+- Secure Monitor library code such as world switching, EL1 context management
+ and interrupt routing.
+ When a Secure-EL1 Payload (SP) is present, for example a Secure OS, the
+ AArch64 EL3 Runtime Software must be integrated with a Secure Payload
+ Dispatcher (SPD) component to customize the interaction with the SP.
+
+- A Test SP and SPD to demonstrate AArch64 Secure Monitor functionality and SP
+ interaction with PSCI.
+
+- SPDs for the `OP-TEE Secure OS`_, `NVIDIA Trusted Little Kernel`_
+ and `Trusty Secure OS`_.
+
+- A Trusted Board Boot implementation, conforming to all mandatory TBBR
+ requirements. This includes image authentication, Firmware Update (or
+ recovery mode), and packaging of the various firmware images into a
+ Firmware Image Package (FIP).
+
+- Pre-integration of TBB with the Arm CryptoCell product, to take advantage of
+ its hardware Root of Trust and crypto acceleration services.
+
+- Reliability, Availability, and Serviceability (RAS) functionality, including
+
+ - A Secure Partition Manager (SPM) to manage Secure Partitions in
+ Secure-EL0, which can be used to implement simple management and
+ security services.
+
+ - An SDEI dispatcher to route interrupt-based SDEI events.
+
+ - An Exception Handling Framework (EHF) that allows dispatching of EL3
+ interrupts to their registered handlers, to facilitate firmware-first
+ error handling.
+
+- A dynamic configuration framework that enables each of the firmware images
+ to be configured at runtime if required by the platform. It also enables
+ loading of a hardware configuration (for example, a kernel device tree)
+ as part of the FIP, to be passed through the firmware stages.
+
+- Support for alternative boot flows, for example to support platforms where
+ the EL3 Runtime Software is loaded using other firmware or a separate
+ secure system processor, or where a non-TF-A ROM expects BL2 to be loaded
+ at EL3.
+
+- Support for the GCC, LLVM and Arm Compiler 6 toolchains.
+
+- Support for combining several libraries into a "romlib" image that may be
+ shared across images to reduce memory footprint. The romlib image is stored
+ in ROM but is accessed through a jump-table that may be stored
+ in read-write memory, allowing for the library code to be patched.
+
+- A prototype implementation of a Secure Partition Manager (SPM) that is based
+ on the SPCI Alpha 1 and SPRT draft specifications.
+
+- Support for ARMv8.3 pointer authentication in the normal and secure worlds.
+ The use of pointer authentication in the normal world is enabled whenever
+ architectural support is available, without the need for additional build
+ flags. Use of pointer authentication in the secure world remains an
+ experimental configuration at this time and requires the ``ENABLE_PAUTH``
+ build flag to be set.
+
+- Position-Independent Executable (PIE) support. Initially for BL31 only, with
+ further support to be added in a future release.
+
+For a full description of functionality and implementation details, please
+see the `Firmware Design`_ and supporting documentation. The `Change Log`_
+provides details of changes made since the last release.
+
+Platforms
+---------
+
+Various AArch32 and AArch64 builds of this release have been tested on r0, r1
+and r2 variants of the `Juno Arm Development Platform`_.
+
+The latest version of the AArch64 build of TF-A has been tested on the following
+Arm FVPs without shifted affinities, and that do not support threaded CPU cores
+(64-bit host machine only).
+
+The FVP models used are Version 11.5 Build 33, unless otherwise stated.
+
+- ``FVP_Base_AEMv8A-AEMv8A``
+- ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
+- ``FVP_Base_RevC-2xAEMv8A``
+- ``FVP_Base_Cortex-A32x4``
+- ``FVP_Base_Cortex-A35x4``
+- ``FVP_Base_Cortex-A53x4``
+- ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
+- ``FVP_Base_Cortex-A55x4``
+- ``FVP_Base_Cortex-A57x1-A53x1``
+- ``FVP_Base_Cortex-A57x2-A53x4``
+- ``FVP_Base_Cortex-A57x4-A53x4``
+- ``FVP_Base_Cortex-A57x4``
+- ``FVP_Base_Cortex-A72x4-A53x4``
+- ``FVP_Base_Cortex-A72x4``
+- ``FVP_Base_Cortex-A73x4-A53x4``
+- ``FVP_Base_Cortex-A73x4``
+- ``FVP_Base_Cortex-A75x4``
+- ``FVP_Base_Cortex-A76x4``
+- ``FVP_Base_Cortex-A76AEx4`` (Tested with internal model)
+- ``FVP_Base_Cortex-A76AEx8`` (Tested with internal model)
+- ``FVP_Base_Neoverse-N1x4`` (Tested with internal model)
+- ``FVP_Base_Deimos``
+- ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
+- ``FVP_CSS_SGM-775`` (Version 11.3 build 42)
+- ``FVP_RD_E1Edge`` (Version 11.3 build 42)
+- ``FVP_RD_N1Edge`` (Version 11.3 build 42)
+- ``Foundation_Platform``
+
+The latest version of the AArch32 build of TF-A has been tested on the following
+Arm FVPs without shifted affinities, and that do not support threaded CPU cores
+(64-bit host machine only).
+
+- ``FVP_Base_AEMv8A-AEMv8A``
+- ``FVP_Base_Cortex-A32x4``
+
+NOTE: The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities.
+
+The Foundation FVP can be downloaded free of charge. The Base FVPs can be
+licensed from Arm. See the `Arm FVP website`_.
+
+All the above platforms have been tested with `Linaro Release 18.04`_.
+
+This release also contains the following platform support:
+
+- Allwinner sun50i_a64 and sun50i_h6
+- Amlogic Meson S905 (GXBB)
+- Amlogic Meson S905x (GXL)
+- Arm Juno Software Development Platform
+- Arm Neoverse N1 System Development Platform (N1SDP)
+- Arm Neoverse Reference Design N1 Edge (RD-N1-Edge) FVP
+- Arm Neoverse Reference Design E1 Edge (RD-E1-Edge) FVP
+- Arm SGI-575 and SGM-775
+- Arm Versatile Express FVP
+- HiKey, HiKey960 and Poplar boards
+- Intel Stratix 10 SoC FPGA
+- Marvell Armada 3700 and 8K
+- MediaTek MT6795 and MT8173 SoCs
+- NVIDIA T132, T186 and T210 SoCs
+- NXP QorIQ LS1043A, i.MX8MM, i.MX8MQ, i.MX8QX, i.MX8QM and i.MX7Solo WaRP7
+- QEMU
+- Raspberry Pi 3
+- Renesas R-Car Generation 3
+- RockChip RK3328, RK3368 and RK3399 SoCs
+- Socionext UniPhier SoC family and SynQuacer SC2A11 SoCs
+- STMicroelectronics STM32MP1
+- Texas Instruments K3 SoCs
+- Xilinx Versal and Zynq UltraScale + MPSoC
+
+Still to come
+-------------
+
+- Support for additional platforms.
+
+- Refinements to Position Independent Executable (PIE) support.
+
+- Refinements to the SPCI-based SPM implementation as the draft SPCI and SPRT
+ specifications continue to evolve.
+
+- Documentation enhancements.
+
+- Ongoing support for new architectural features, CPUs and System IP.
+
+- Ongoing support for new Arm system architecture specifications.
+
+- Ongoing security hardening, optimization and quality improvements.
+
+For a full list of detailed issues in the current code, please see the `Change
+Log`_ and the `issue tracker`_.
+
+Getting started
+---------------
+
+See the `User Guide`_ for instructions on how to download, install, build and
+use TF-A with the Arm `FVP`_\ s.
+
+See the `Firmware Design`_ for information on how TF-A works.
+
+See the `Porting Guide`_ as well for information about how to use this
+software on another Armv7-A or Armv8-A platform.
+
+See the `Contributing Guidelines`_ for information on how to contribute to this
+project and the `Acknowledgments`_ file for a list of contributors to the
+project.
+
+IRC channel
+~~~~~~~~~~~
+
+Development discussion takes place on the #trusted-firmware-a channel
+on the Freenode IRC network. This is not an official support channel.
+If you have an issue to raise, please use the `issue tracker`_.
+
+Feedback and support
+~~~~~~~~~~~~~~~~~~~~
+
+Arm welcomes any feedback on TF-A. If you think you have found a security
+vulnerability, please report this using the process defined in the TF-A
+`Security Center`_. For all other feedback, please use the
+`issue tracker`_.
+
+Arm licensees may contact Arm directly via their partner managers.
+
+Security advisories
+-------------------
+
+- `Security Advisory TFV-1`_
+- `Security Advisory TFV-2`_
+- `Security Advisory TFV-3`_
+- `Security Advisory TFV-4`_
+- `Security Advisory TFV-5`_
+- `Security Advisory TFV-6`_
+- `Security Advisory TFV-7`_
+- `Security Advisory TFV-8`_
+
+
+--------------
+
+*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _Armv7-A and Armv8-A: https://developer.arm.com/products/architecture/a-profile
+.. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php
+.. _Power State Coordination Interface (PSCI): PSCI_
+.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
+.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
+.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
+.. _System Control and Management Interface (SCMI): SCMI_
+.. _SCMI: http://infocenter.arm.com/help/topic/com.arm.doc.den0056a/DEN0056A_System_Control_and_Management_Interface.pdf
+.. _Software Delegated Exception Interface (SDEI): SDEI_
+.. _SDEI: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
+.. _Juno Arm Development Platform: http://www.arm.com/products/tools/development-boards/versatile-express/juno-arm-development-platform.php
+.. _Arm FVP website: FVP_
+.. _FVP: https://developer.arm.com/products/system-design/fixed-virtual-platforms
+.. _Linaro Release 18.04: https://community.arm.com/dev-platforms/b/documents/posts/linaro-release-notes-deprecated#LinaroRelease18.04
+.. _OP-TEE Secure OS: https://github.com/OP-TEE/optee_os
+.. _NVIDIA Trusted Little Kernel: http://nv-tegra.nvidia.com/gitweb/?p=3rdparty/ote_partner/tlk.git;a=summary
+.. _Trusty Secure OS: https://source.android.com/security/trusty
+.. _trustedfirmware.org: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
+.. _issue tracker: https://developer.trustedfirmware.org/project/board/1/
+.. _Security Center: ./docs/security-center.rst
+.. _license: ./license.rst
+.. _Contributing Guidelines: ./contributing.rst
+.. _Acknowledgments: ./acknowledgements.rst
+.. _Firmware Design: ./docs/firmware-design.rst
+.. _Change Log: ./docs/change-log.rst
+.. _User Guide: ./docs/user-guide.rst
+.. _Porting Guide: ./docs/porting-guide.rst
+.. _FreeBSD: http://www.freebsd.org
+.. _SCC: http://www.simple-cc.org/
+.. _Security Advisory TFV-1: ./docs/security_advisories/security-advisory-tfv-1.rst
+.. _Security Advisory TFV-2: ./docs/security_advisories/security-advisory-tfv-2.rst
+.. _Security Advisory TFV-3: ./docs/security_advisories/security-advisory-tfv-3.rst
+.. _Security Advisory TFV-4: ./docs/security_advisories/security-advisory-tfv-4.rst
+.. _Security Advisory TFV-5: ./docs/security_advisories/security-advisory-tfv-5.rst
+.. _Security Advisory TFV-6: ./docs/security_advisories/security-advisory-tfv-6.rst
+.. _Security Advisory TFV-7: ./docs/security_advisories/security-advisory-tfv-7.rst
+.. _Security Advisory TFV-8: ./docs/security_advisories/security-advisory-tfv-8.rst
+.. _Trusted Firmware-A Documentation Contents: ./docs/contents.rst
+++ /dev/null
-TF-A Release Information
-========================
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
---------------
-
-Project Release Cadence
------------------------
-
-The project currently aims to do a release once every 6 months which will be
-tagged on the master branch. There will be a code freeze (stop merging
-non-essential PRs) up to 4 weeks prior to the target release date. The release
-candidates will start appearing after this and only bug fixes or updates
-required for the release will be merged. The maintainers are free to use their
-judgement on what PRs are essential for the release. A release branch may be
-created after code freeze if there are significant PRs that need merging onto
-the integration branch during the merge window.
-
-The release testing will be performed on release candidates and depending on
-issues found, additional release candidates may be created to fix the issues.
-
-::
-
- |<----------6 months---------->|
- |<---4 weeks--->| |<---4 weeks--->|
- +-----------------------------------------------------------> time
- | | | |
- code freeze ver w.x code freeze ver y.z
-
-
-Upcoming Releases
-~~~~~~~~~~~~~~~~~
-
-These are the estimated dates for the upcoming release. These may change
-depending on project requirement and partner feedback.
-
-+-----------------+---------------------------+------------------------------+
-| Release Version | Target Date | Expected Code Freeze |
-+=================+===========================+==============================+
-| v2.0 | 1st week of Oct '18 | 1st week of Sep '18 |
-+-----------------+---------------------------+------------------------------+
-| v2.1 | 5th week of Mar '19 | 1st week of Mar '19 |
-+-----------------+---------------------------+------------------------------+
-
-Removal of Deprecated Interfaces
---------------------------------
-
-As mentioned in the `Platform compatibility policy`_, this is a live document
-cataloging all the deprecated interfaces in TF-A project and the Release version
-after which it will be removed.
-
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| Interface | Deprecation | Removed | Comments |
-| | Date | after | |
-| | | Release | |
-+================================+=============+=========+=========================================================+
-| Legacy Console API | Jan '18 | v2.1 | Deprecated in favour of ``MULTI_CONSOLE_API`` |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| Weak default | Oct '18 | v2.1 | The default implementations are defined in |
-| ``plat_crash_console_*`` | | | `crash_console_helpers.S`_. The platforms have to |
-| APIs | | | define ``plat_crash_console_*``. |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| ``finish_console_register`` | Oct '18 | v2.1 | The old version of the macro is deprecated. See commit |
-| macro in | | | cc5859c_ for more details. |
-| ``MULTI_CONSOLE_API`` | | | |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| Types ``tzc_action_t`` and | Oct '18 | v2.1 | Using logical operations such as OR in enumerations |
-| ``tzc_region_attributes_t`` | | | goes against the MISRA guidelines. |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| Macro ``EL_IMPLEMENTED()`` | Oct '18 | v2.1 | Deprecated in favour of ``el_implemented()``. |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| ``get_afflvl_shift()``, | Dec '18 | v2.1 | Removed. |
-| ``mpidr_mask_lower_afflvls()``,| | | |
-| and ``eret()``. | | | |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-| Extra include paths in the | Jan '18 | v2.1 | Now it is needed to use the full path of the common |
-| Makefile in ``INCLUDES``. | | | header files. More information in commit 09d40e0e0828_. |
-+--------------------------------+-------------+---------+---------------------------------------------------------+
-
-*Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _Platform compatibility policy: platform-compatibility-policy.rst
-.. _crash_console_helpers.S: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/common/aarch64/crash_console_helpers.S
-.. _cc5859c: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=cc5859ca19ff546c35eb0331000dae090b6eabcf
-.. _09d40e0e0828: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/commit/?id=09d40e0e08283a249e7dce0e106c07c5141f9b7e
+++ /dev/null
-Trusted Firmware-A reset design
-===============================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-This document describes the high-level design of the framework to handle CPU
-resets in Trusted Firmware-A (TF-A). It also describes how the platform
-integrator can tailor this code to the system configuration to some extent,
-resulting in a simplified and more optimised boot flow.
-
-This document should be used in conjunction with the `Firmware Design`_, which
-provides greater implementation details around the reset code, specifically
-for the cold boot path.
-
-General reset code flow
------------------------
-
-The TF-A reset code is implemented in BL1 by default. The following high-level
-diagram illustrates this:
-
-|Default reset code flow|
-
-This diagram shows the default, unoptimised reset flow. Depending on the system
-configuration, some of these steps might be unnecessary. The following sections
-guide the platform integrator by indicating which build options exclude which
-steps, depending on the capability of the platform.
-
-Note: If BL31 is used as the TF-A entry point instead of BL1, the diagram
-above is still relevant, as all these operations will occur in BL31 in
-this case. Please refer to section 6 "Using BL31 entrypoint as the reset
-address" for more information.
-
-Programmable CPU reset address
-------------------------------
-
-By default, TF-A assumes that the CPU reset address is not programmable.
-Therefore, all CPUs start at the same address (typically address 0) whenever
-they reset. Further logic is then required to identify whether it is a cold or
-warm boot to direct CPUs to the right execution path.
-
-If the reset vector address (reflected in the reset vector base address register
-``RVBAR_EL3``) is programmable then it is possible to make each CPU start directly
-at the right address, both on a cold and warm reset. Therefore, the boot type
-detection can be skipped, resulting in the following boot flow:
-
-|Reset code flow with programmable reset address|
-
-To enable this boot flow, compile TF-A with ``PROGRAMMABLE_RESET_ADDRESS=1``.
-This option only affects the TF-A reset image, which is BL1 by default or BL31 if
-``RESET_TO_BL31=1``.
-
-On both the FVP and Juno platforms, the reset vector address is not programmable
-so both ports use ``PROGRAMMABLE_RESET_ADDRESS=0``.
-
-Cold boot on a single CPU
--------------------------
-
-By default, TF-A assumes that several CPUs may be released out of reset.
-Therefore, the cold boot code has to arbitrate access to hardware resources
-shared amongst CPUs. This is done by nominating one of the CPUs as the primary,
-which is responsible for initialising shared hardware and coordinating the boot
-flow with the other CPUs.
-
-If the platform guarantees that only a single CPU will ever be brought up then
-no arbitration is required. The notion of primary/secondary CPU itself no longer
-applies. This results in the following boot flow:
-
-|Reset code flow with single CPU released out of reset|
-
-To enable this boot flow, compile TF-A with ``COLD_BOOT_SINGLE_CPU=1``. This
-option only affects the TF-A reset image, which is BL1 by default or BL31 if
-``RESET_TO_BL31=1``.
-
-On both the FVP and Juno platforms, although only one core is powered up by
-default, there are platform-specific ways to release any number of cores out of
-reset. Therefore, both platform ports use ``COLD_BOOT_SINGLE_CPU=0``.
-
-Programmable CPU reset address, Cold boot on a single CPU
----------------------------------------------------------
-
-It is obviously possible to combine both optimisations on platforms that have
-a programmable CPU reset address and which release a single CPU out of reset.
-This results in the following boot flow:
-
-
-|Reset code flow with programmable reset address and single CPU released out of reset|
-
-To enable this boot flow, compile TF-A with both ``COLD_BOOT_SINGLE_CPU=1``
-and ``PROGRAMMABLE_RESET_ADDRESS=1``. These options only affect the TF-A reset
-image, which is BL1 by default or BL31 if ``RESET_TO_BL31=1``.
-
-Using BL31 entrypoint as the reset address
-------------------------------------------
-
-On some platforms the runtime firmware (BL3x images) for the application
-processors are loaded by some firmware running on a secure system processor
-on the SoC, rather than by BL1 and BL2 running on the primary application
-processor. For this type of SoC it is desirable for the application processor
-to always reset to BL31 which eliminates the need for BL1 and BL2.
-
-TF-A provides a build-time option ``RESET_TO_BL31`` that includes some additional
-logic in the BL31 entry point to support this use case.
-
-In this configuration, the platform's Trusted Boot Firmware must ensure that
-BL31 is loaded to its runtime address, which must match the CPU's ``RVBAR_EL3``
-reset vector base address, before the application processor is powered on.
-Additionally, platform software is responsible for loading the other BL3x images
-required and providing entry point information for them to BL31. Loading these
-images might be done by the Trusted Boot Firmware or by platform code in BL31.
-
-Although the Arm FVP platform does not support programming the reset base
-address dynamically at run-time, it is possible to set the initial value of the
-``RVBAR_EL3`` register at start-up. This feature is provided on the Base FVP only.
-It allows the Arm FVP port to support the ``RESET_TO_BL31`` configuration, in
-which case the ``bl31.bin`` image must be loaded to its run address in Trusted
-SRAM and all CPU reset vectors be changed from the default ``0x0`` to this run
-address. See the `User Guide`_ for details of running the FVP models in this way.
-
-Although technically it would be possible to program the reset base address with
-the right support in the SCP firmware, this is currently not implemented so the
-Juno port doesn't support the ``RESET_TO_BL31`` configuration.
-
-The ``RESET_TO_BL31`` configuration requires some additions and changes in the
-BL31 functionality:
-
-Determination of boot path
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In this configuration, BL31 uses the same reset framework and code as the one
-described for BL1 above. Therefore, it is affected by the
-``PROGRAMMABLE_RESET_ADDRESS`` and ``COLD_BOOT_SINGLE_CPU`` build options in the
-same way.
-
-In the default, unoptimised BL31 reset flow, on a warm boot a CPU is directed
-to the PSCI implementation via a platform defined mechanism. On a cold boot,
-the platform must place any secondary CPUs into a safe state while the primary
-CPU executes a modified BL31 initialization, as described below.
-
-Platform initialization
-~~~~~~~~~~~~~~~~~~~~~~~
-
-In this configuration, when the CPU resets to BL31 there are no parameters that
-can be passed in registers by previous boot stages. Instead, the platform code
-in BL31 needs to know, or be able to determine, the location of the BL32 (if
-required) and BL33 images and provide this information in response to the
-``bl31_plat_get_next_image_ep_info()`` function.
-
-Additionally, platform software is responsible for carrying out any security
-initialisation, for example programming a TrustZone address space controller.
-This might be done by the Trusted Boot Firmware or by platform code in BL31.
-
---------------
-
-*Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _Firmware Design: firmware-design.rst
-.. _User Guide: user-guide.rst
-
-.. |Default reset code flow| image:: diagrams/default_reset_code.png?raw=true
-.. |Reset code flow with programmable reset address| image:: diagrams/reset_code_no_boot_type_check.png?raw=true
-.. |Reset code flow with single CPU released out of reset| image:: diagrams/reset_code_no_cpu_check.png?raw=true
-.. |Reset code flow with programmable reset address and single CPU released out of reset| image:: diagrams/reset_code_no_checks.png?raw=true
+++ /dev/null
-Library at ROM
-==============
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-This document provides an overview of the "library at ROM" implementation in
-Trusted Firmware-A (TF-A).
-
-Introduction
-~~~~~~~~~~~~
-
-The "library at ROM" feature allows platforms to build a library of functions to
-be placed in ROM. This reduces SRAM usage by utilising the available space in
-ROM. The "library at ROM" contains a jump table with the list of functions that
-are placed in ROM. The capabilities of the "library at ROM" are:
-
-1. Functions can be from one or several libraries.
-
-2. Functions can be patched after they have been programmed into ROM.
-
-3. Platform-specific libraries can be placed in ROM.
-
-4. Functions can be accessed by one or more BL images.
-
-Index file
-~~~~~~~~~~
-
-.. image:: diagrams/romlib_design.png
- :width: 600
-
-Library at ROM is described by an index file with the list of functions to be
-placed in ROM. The index file is platform specific and its format is:
-
-::
-
- lib function [patch]
-
- lib -- Name of the library the function belongs to
- function -- Name of the function to be placed in library at ROM
- [patch] -- Option to patch the function
-
-It is also possible to insert reserved spaces in the list by using the keyword
-"reserved" rather than the "lib" and "function" names as shown below:
-
-::
-
- reserved reserved
-
-The reserved spaces can be used to add more functions in the future without
-affecting the order and location of functions already existing in the jump
-table. Also, for additional flexibility and modularity, the index file can
-include other index files.
-
-For an index file example, refer to ``lib/romlib/jmptbl.i``.
-
-Wrapper functions
-~~~~~~~~~~~~~~~~~
-
-.. image:: diagrams/romlib_wrapper.png
- :width: 600
-
-When invoking a function of the "library at ROM", the calling sequence is as
-follows:
-
-BL image --> wrapper function --> jump table entry --> library at ROM
-
-The index file is used to create a jump table which is placed in ROM. Then, the
-wrappers refer to the jump table to call the "library at ROM" functions. The
-wrappers essentially contain a branch instruction to the jump table entry
-corresponding to the original function. Finally, the original function in the BL
-image(s) is replaced with the wrapper function.
-
-The "library at ROM" contains a necessary init function that initialises the
-global variables defined by the functions inside "library at ROM".
-
-Scripts
-~~~~~~~
-
-There are several scripts that generate the necessary files for the "library at
-ROM" to work:
-
-1. ``gentbl.sh`` - Generates the jump table by parsing the index file.
-
-2. ``genvar.sh`` - Generates the jump table global variable (**not** the jump
- table itself) with the absolute address in ROM. This global variable is,
- basically, a pointer to the jump table.
-
-3. ``genwrappers.sh`` - Generates a wrapper function for each entry in the index
- file except for the ones that contain the keyword ``patch``. The generated
- wrapper file is called ``<lib>_<fn_name>.S``.
-
-Patching of functions in library at ROM
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``genwrappers.sh`` script does not generate wrappers for the entries in the
-index file that contain the keyword ``patch``. Thus, it allows calling the
-function from the actual library by breaking the link to the "library at ROM"
-version of this function.
-
-The calling sequence for a patched function is as follows:
-
-BL image --> function
-
-Build library at ROM
-~~~~~~~~~~~~~~~~~~~~~
-
-The environment variable ``CROSS_COMPILE`` must be set as per the user guide.
-In the below example the usage of ROMLIB together with mbed TLS is demonstrated
-to showcase the benefits of library at ROM - it's not mandatory.
-
-::
-
- make PLAT=fvp \
- MBEDTLS_DIR=</path/to/mbedtls/> \
- TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \
- ARM_ROTPK_LOCATION=devel_rsa \
- ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
- BL33=</path/to/bl33.bin> \
- USE_ROMLIB=1 \
- all fip
-
-Known issue
------------
-When building library at ROM, a clean build is always required. This is
-necessary when changes are made to the index files, e.g. adding new functions,
-patching existing ones etc.
-
---------------
-
-*Copyright (c) 2019, Arm Limited. All rights reserved.*
+++ /dev/null
-Trusted Firmware-A EL3 runtime service writer's guide
-=====================================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
---------------
-
-Introduction
-------------
-
-This document describes how to add a runtime service to the EL3 Runtime
-Firmware component of Trusted Firmware-A (TF-A), BL31.
-
-Software executing in the normal world and in the trusted world at exception
-levels lower than EL3 will request runtime services using the Secure Monitor
-Call (SMC) instruction. These requests will follow the convention described in
-the SMC Calling Convention PDD (`SMCCC`_). The `SMCCC`_ assigns function
-identifiers to each SMC request and describes how arguments are passed and
-results are returned.
-
-SMC Functions are grouped together based on the implementor of the service, for
-example a subset of the Function IDs are designated as "OEM Calls" (see `SMCCC`_
-for full details). The EL3 runtime services framework in BL31 enables the
-independent implementation of services for each group, which are then compiled
-into the BL31 image. This simplifies the integration of common software from
-Arm to support `PSCI`_, Secure Monitor for a Trusted OS and SoC specific
-software. The common runtime services framework ensures that SMC Functions are
-dispatched to their respective service implementation - the `Firmware Design`_
-provides details of how this is achieved.
-
-The interface and operation of the runtime services depends heavily on the
-concepts and definitions described in the `SMCCC`_, in particular SMC Function
-IDs, Owning Entity Numbers (OEN), Fast and Standard calls, and the SMC32 and
-SMC64 calling conventions. Please refer to that document for a full explanation
-of these terms.
-
-Owning Entities, Call Types and Function IDs
---------------------------------------------
-
-The SMC Function Identifier includes a OEN field. These values and their
-meaning are described in `SMCCC`_ and summarized in table 1 below. Some entities
-are allocated a range of of OENs. The OEN must be interpreted in conjunction
-with the SMC call type, which is either *Fast* or *Yielding*. Fast calls are
-uninterruptible whereas Yielding calls can be pre-empted. The majority of
-Owning Entities only have allocated ranges for Fast calls: Yielding calls are
-reserved exclusively for Trusted OS providers or for interoperability with
-legacy 32-bit software that predates the `SMCCC`_.
-
-::
-
- Type OEN Service
- Fast 0 Arm Architecture calls
- Fast 1 CPU Service calls
- Fast 2 SiP Service calls
- Fast 3 OEM Service calls
- Fast 4 Standard Service calls
- Fast 5-47 Reserved for future use
- Fast 48-49 Trusted Application calls
- Fast 50-63 Trusted OS calls
-
- Yielding 0- 1 Reserved for existing Armv7-A calls
- Yielding 2-63 Trusted OS Standard Calls
-
-*Table 1: Service types and their corresponding Owning Entity Numbers*
-
-Each individual entity can allocate the valid identifiers within the entity
-range as they need - it is not necessary to coordinate with other entities of
-the same type. For example, two SoC providers can use the same Function ID
-within the SiP Service calls OEN range to mean different things - as these
-calls should be specific to the SoC. The Standard Runtime Calls OEN is used for
-services defined by Arm standards, such as `PSCI`_.
-
-The SMC Function ID also indicates whether the call has followed the SMC32
-calling convention, where all parameters are 32-bit, or the SMC64 calling
-convention, where the parameters are 64-bit. The framework identifies and
-rejects invalid calls that use the SMC64 calling convention but that originate
-from an AArch32 caller.
-
-The EL3 runtime services framework uses the call type and OEN to identify a
-specific handler for each SMC call, but it is expected that an individual
-handler will be responsible for all SMC Functions within a given service type.
-
-Getting started
----------------
-
-TF-A has a `services`_ directory in the source tree under which
-each owning entity can place the implementation of its runtime service. The
-`PSCI`_ implementation is located here in the `lib/psci`_ directory.
-
-Runtime service sources will need to include the `runtime_svc.h`_ header file.
-
-Registering a runtime service
------------------------------
-
-A runtime service is registered using the ``DECLARE_RT_SVC()`` macro, specifying
-the name of the service, the range of OENs covered, the type of service and
-initialization and call handler functions.
-
-::
-
- #define DECLARE_RT_SVC(_name, _start, _end, _type, _setup, _smch)
-
-- ``_name`` is used to identify the data structure declared by this macro, and
- is also used for diagnostic purposes
-
-- ``_start`` and ``_end`` values must be based on the ``OEN_*`` values defined in
- `smccc.h`_
-
-- ``_type`` must be one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD``
-
-- ``_setup`` is the initialization function with the ``rt_svc_init`` signature:
-
- .. code:: c
-
- typedef int32_t (*rt_svc_init)(void);
-
-- ``_smch`` is the SMC handler function with the ``rt_svc_handle`` signature:
-
- .. code:: c
-
- typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
- u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4,
- void *cookie,
- void *handle,
- u_register_t flags);
-
-Details of the requirements and behavior of the two callbacks is provided in
-the following sections.
-
-During initialization the services framework validates each declared service
-to ensure that the following conditions are met:
-
-#. The ``_start`` OEN is not greater than the ``_end`` OEN
-#. The ``_end`` OEN does not exceed the maximum OEN value (63)
-#. The ``_type`` is one of ``SMC_TYPE_FAST`` or ``SMC_TYPE_YIELD``
-#. ``_setup`` and ``_smch`` routines have been specified
-
-`std_svc_setup.c`_ provides an example of registering a runtime service:
-
-.. code:: c
-
- /* Register Standard Service Calls as runtime service */
- DECLARE_RT_SVC(
- std_svc,
- OEN_STD_START,
- OEN_STD_END,
- SMC_TYPE_FAST,
- std_svc_setup,
- std_svc_smc_handler
- );
-
-Initializing a runtime service
-------------------------------
-
-Runtime services are initialized once, during cold boot, by the primary CPU
-after platform and architectural initialization is complete. The framework
-performs basic validation of the declared service before calling
-the service initialization function (``_setup`` in the declaration). This
-function must carry out any essential EL3 initialization prior to receiving a
-SMC Function call via the handler function.
-
-On success, the initialization function must return ``0``. Any other return value
-will cause the framework to issue a diagnostic:
-
-::
-
- Error initializing runtime service <name of the service>
-
-and then ignore the service - the system will continue to boot but SMC calls
-will not be passed to the service handler and instead return the *Unknown SMC
-Function ID* result ``0xFFFFFFFF``.
-
-If the system must not be allowed to proceed without the service, the
-initialization function must itself cause the firmware boot to be halted.
-
-If the service uses per-CPU data this must either be initialized for all CPUs
-during this call, or be done lazily when a CPU first issues an SMC call to that
-service.
-
-Handling runtime service requests
----------------------------------
-
-SMC calls for a service are forwarded by the framework to the service's SMC
-handler function (``_smch`` in the service declaration). This function must have
-the following signature:
-
-.. code:: c
-
- typedef uintptr_t (*rt_svc_handle_t)(uint32_t smc_fid,
- u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4,
- void *cookie,
- void *handle,
- u_register_t flags);
-
-The handler is responsible for:
-
-#. Determining that ``smc_fid`` is a valid and supported SMC Function ID,
- otherwise completing the request with the *Unknown SMC Function ID*:
-
- .. code:: c
-
- SMC_RET1(handle, SMC_UNK);
-
-#. Determining if the requested function is valid for the calling security
- state. SMC Calls can be made from both the normal and trusted worlds and
- the framework will forward all calls to the service handler.
-
- The ``flags`` parameter to this function indicates the caller security state
- in bit[0], where a value of ``1`` indicates a non-secure caller. The
- ``is_caller_secure(flags)`` and ``is_caller_non_secure(flags)`` can be used to
- test this condition.
-
- If invalid, the request should be completed with:
-
- .. code:: c
-
- SMC_RET1(handle, SMC_UNK);
-
-#. Truncating parameters for calls made using the SMC32 calling convention.
- Such calls can be determined by checking the CC field in bit[30] of the
- ``smc_fid`` parameter, for example by using:
-
- ::
-
- if (GET_SMC_CC(smc_fid) == SMC_32) ...
-
- For such calls, the upper bits of the parameters x1-x4 and the saved
- parameters X5-X7 are UNDEFINED and must be explicitly ignored by the
- handler. This can be done by truncating the values to a suitable 32-bit
- integer type before use, for example by ensuring that functions defined
- to handle individual SMC Functions use appropriate 32-bit parameters.
-
-#. Providing the service requested by the SMC Function, utilizing the
- immediate parameters x1-x4 and/or the additional saved parameters X5-X7.
- The latter can be retrieved using the ``SMC_GET_GP(handle, ref)`` function,
- supplying the appropriate ``CTX_GPREG_Xn`` reference, e.g.
-
- .. code:: c
-
- uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
-
-#. Implementing the standard SMC32 Functions that provide information about
- the implementation of the service. These are the Call Count, Implementor
- UID and Revision Details for each service documented in section 6 of the
- `SMCCC`_.
-
- TF-A expects owning entities to follow this recommendation.
-
-#. Returning the result to the caller. The `SMCCC`_ allows for up to 256 bits
- of return value in SMC64 using X0-X3 and 128 bits in SMC32 using W0-W3. The
- framework provides a family of macros to set the multi-register return
- value and complete the handler:
-
- .. code:: c
-
- SMC_RET1(handle, x0);
- SMC_RET2(handle, x0, x1);
- SMC_RET3(handle, x0, x1, x2);
- SMC_RET4(handle, x0, x1, x2, x3);
-
-The ``cookie`` parameter to the handler is reserved for future use and can be
-ignored. The ``handle`` is returned by the SMC handler - completion of the
-handler function must always be via one of the ``SMC_RETn()`` macros.
-
-NOTE: The PSCI and Test Secure-EL1 Payload Dispatcher services do not follow
-all of the above requirements yet.
-
-Services that contain multiple sub-services
--------------------------------------------
-
-It is possible that a single owning entity implements multiple sub-services. For
-example, the Standard calls service handles ``0x84000000``-``0x8400FFFF`` and
-``0xC4000000``-``0xC400FFFF`` functions. Within that range, the `PSCI`_ service
-handles the ``0x84000000``-``0x8400001F`` and ``0xC4000000``-``0xC400001F`` functions.
-In that respect, `PSCI`_ is a 'sub-service' of the Standard calls service. In
-future, there could be additional such sub-services in the Standard calls
-service which perform independent functions.
-
-In this situation it may be valuable to introduce a second level framework to
-enable independent implementation of sub-services. Such a framework might look
-very similar to the current runtime services framework, but using a different
-part of the SMC Function ID to identify the sub-service. TF-A does not provide
-such a framework at present.
-
-Secure-EL1 Payload Dispatcher service (SPD)
--------------------------------------------
-
-Services that handle SMC Functions targeting a Trusted OS, Trusted Application,
-or other Secure-EL1 Payload are special. These services need to manage the
-Secure-EL1 context, provide the *Secure Monitor* functionality of switching
-between the normal and secure worlds, deliver SMC Calls through to Secure-EL1
-and generally manage the Secure-EL1 Payload through CPU power-state transitions.
-
-TODO: Provide details of the additional work required to implement a SPD and
-the BL31 support for these services. Or a reference to the document that will
-provide this information....
-
---------------
-
-*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022c/DEN0022C_Power_State_Coordination_Interface.pdf
-.. _Firmware Design: ./firmware-design.rst
-.. _services: ../services
-.. _lib/psci: ../lib/psci
-.. _runtime_svc.h: ../include/common/runtime_svc.h
-.. _smccc.h: ../include/lib/smccc.h
-.. _std_svc_setup.c: ../services/std_svc/std_svc_setup.c
+++ /dev/null
-Software Delegated Exception Interface
-======================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
- :depth: 2
-
-This document provides an overview of the SDEI dispatcher implementation in
-Trusted Firmware-A (TF-A).
-
-Introduction
-------------
-
-`Software Delegated Exception Interface`_ (SDEI) is an Arm specification for
-Non-secure world to register handlers with firmware to receive notifications
-about system events. Firmware will first receive the system events by way of
-asynchronous exceptions and, in response, arranges for the registered handler to
-execute in the Non-secure EL.
-
-Normal world software that interacts with the SDEI dispatcher (makes SDEI
-requests and receives notifications) is referred to as the *SDEI Client*. A
-client receives the event notification at the registered handler even when it
-was executing with exceptions masked. The list of SDEI events available to the
-client are specific to the platform [#std-event]_. See also `Determining client
-EL`_.
-
-.. _general SDEI dispatch:
-
-The following figure depicts a general sequence involving SDEI client executing
-at EL2 and an event dispatch resulting from the triggering of a bound interrupt.
-A commentary is provided below:
-
-.. image:: plantuml/sdei_general.svg
-
-As part of initialisation, the SDEI client binds a Non-secure interrupt [1], and
-the SDEI dispatcher returns a platform dynamic event number [2]. The client then
-registers a handler for that event [3], enables the event [5], and unmasks all
-events on the current PE [7]. This sequence is typical of an SDEI client, but it
-may involve additional SDEI calls.
-
-At a later point in time, when the bound interrupt triggers [9], it's trapped to
-EL3. The interrupt is handed over to the SDEI dispatcher, which then arranges to
-execute the registered handler [10]. The client terminates its execution with
-``SDEI_EVENT_COMPLETE`` [11], following which the dispatcher resumes the
-original EL2 execution [13]. Note that the SDEI interrupt remains active until
-the client handler completes, at which point EL3 does EOI [12].
-
-Other than events bound to interrupts (as depicted in the sequence above, SDEI
-events can be explicitly dispatched in response to other exceptions, for
-example, upon receiving an *SError* or *Synchronous External Abort*. See
-`Explicit dispatch of events`_.
-
-The remainder of this document only discusses the design and implementation of
-SDEI dispatcher in TF-A, and assumes that the reader is familiar with the SDEI
-specification, the interfaces, and their requirements.
-
-.. [#std-event] Except event 0, which is defined by the SDEI specification as a
- standard event.
-
-Defining events
----------------
-
-A platform choosing to include the SDEI dispatcher must also define the events
-available on the platform, along with their attributes.
-
-The platform is expected to provide two arrays of event descriptors: one for
-private events, and another for shared events. The SDEI dispatcher provides
-``SDEI_PRIVATE_EVENT()`` and ``SDEI_SHARED_EVENT()`` macros to populate the
-event descriptors. Both macros take 3 arguments:
-
-- The event number: this must be a positive 32-bit integer.
-
-- For an event that has a backing interrupt, the interrupt number the event is
- bound to:
-
- - If it's not applicable to an event, this shall be left as ``0``.
-
- - If the event is dynamic, this should be specified as ``SDEI_DYN_IRQ``.
-
-- A bit map of `Event flags`_.
-
-To define event 0, the macro ``SDEI_DEFINE_EVENT_0()`` should be used. This
-macro takes only one parameter: an SGI number to signal other PEs.
-
-To define an event that's meant to be `explicitly dispatched`__ (i.e., not as a
-result of receiving an SDEI interrupt), the macro ``SDEI_EXPLICIT_EVENT()``
-should be used. It accepts two parameters:
-
-.. __: `Explicit dispatch of events`_
-
-- The event number (as above);
-
-- Event priority: ``SDEI_MAPF_CRITICAL`` or ``SDEI_MAPF_NORMAL``, as described
- below.
-
-Once the event descriptor arrays are defined, they should be exported to the
-SDEI dispatcher using the ``REGISTER_SDEI_MAP()`` macro, passing it the pointers
-to the private and shared event descriptor arrays, respectively. Note that the
-``REGISTER_SDEI_MAP()`` macro must be used in the same file where the arrays are
-defined.
-
-Regarding event descriptors:
-
-- For Event 0:
-
- - There must be exactly one descriptor in the private array, and none in the
- shared array.
-
- - The event should be defined using ``SDEI_DEFINE_EVENT_0()``.
-
- - Must be bound to a Secure SGI on the platform.
-
-- Explicit events should only be used in the private array.
-
-- Statically bound shared and private interrupts must be bound to shared and
- private interrupts on the platform, respectively. See the section on
- `interrupt configuration`__.
-
- .. __: `Configuration within Exception Handling Framework`_
-
-- Both arrays should be one-dimensional. The ``REGISTER_SDEI_MAP()`` macro
- takes care of replicating private events for each PE on the platform.
-
-- Both arrays must be sorted in the increasing order of event number.
-
-The SDEI specification doesn't have provisions for discovery of available events
-on the platform. The list of events made available to the client, along with
-their semantics, have to be communicated out of band; for example, through
-Device Trees or firmware configuration tables.
-
-See also `Event definition example`_.
-
-Event flags
-~~~~~~~~~~~
-
-Event flags describe the properties of the event. They are bit maps that can be
-``OR``\ ed to form parameters to macros that `define events`__.
-
-.. __: `Defining events`_
-
-- ``SDEI_MAPF_DYNAMIC``: Marks the event as dynamic. Dynamic events can be
- bound to (or released from) any Non-secure interrupt at runtime via the
- ``SDEI_INTERRUPT_BIND`` and ``SDEI_INTERRUPT_RELEASE`` calls.
-
-- ``SDEI_MAPF_BOUND``: Marks the event as statically bound to an interrupt.
- These events cannot be re-bound at runtime.
-
-- ``SDEI_MAPF_NORMAL``: Marks the event as having *Normal* priority. This is
- the default priority.
-
-- ``SDEI_MAPF_CRITICAL``: Marks the event as having *Critical* priority.
-
-Event definition example
-------------------------
-
-.. code:: c
-
- static sdei_ev_map_t plat_private_sdei[] = {
- /* Event 0 definition */
- SDEI_DEFINE_EVENT_0(8),
-
- /* PPI */
- SDEI_PRIVATE_EVENT(8, 23, SDEI_MAPF_BOUND),
-
- /* Dynamic private events */
- SDEI_PRIVATE_EVENT(100, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
- SDEI_PRIVATE_EVENT(101, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
-
- /* Events for explicit dispatch */
- SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_NORMAL);
- SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_CRITICAL);
- };
-
- /* Shared event mappings */
- static sdei_ev_map_t plat_shared_sdei[] = {
- SDEI_SHARED_EVENT(804, 0, SDEI_MAPF_DYNAMIC),
-
- /* Dynamic shared events */
- SDEI_SHARED_EVENT(3000, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
- SDEI_SHARED_EVENT(3001, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
- };
-
- /* Export SDEI events */
- REGISTER_SDEI_MAP(plat_private_sdei, plat_shared_sdei);
-
-Configuration within Exception Handling Framework
--------------------------------------------------
-
-The SDEI dispatcher functions alongside the Exception Handling Framework. This
-means that the platform must assign priorities to both Normal and Critical SDEI
-interrupts for the platform:
-
-- Install priority descriptors for Normal and Critical SDEI interrupts.
-
-- For those interrupts that are statically bound (i.e. events defined as having
- the ``SDEI_MAPF_BOUND`` property), enumerate their properties for the GIC
- driver to configure interrupts accordingly.
-
- The interrupts must be configured to target EL3. This means that they should
- be configured as *Group 0*. Additionally, on GICv2 systems, the build option
- ``GICV2_G0_FOR_EL3`` must be set to ``1``.
-
-See also `SDEI porting requirements`_.
-
-Determining client EL
----------------------
-
-The SDEI specification requires that the *physical* SDEI client executes in the
-highest Non-secure EL implemented on the system. This means that the dispatcher
-will only allow SDEI calls to be made from:
-
-- EL2, if EL2 is implemented. The Hypervisor is expected to implement a
- *virtual* SDEI dispatcher to support SDEI clients in Guest Operating Systems
- executing in Non-secure EL1.
-
-- Non-secure EL1, if EL2 is not implemented or disabled.
-
-See the function ``sdei_client_el()`` in ``sdei_private.h``.
-
-Explicit dispatch of events
----------------------------
-
-Typically, an SDEI event dispatch is caused by the PE receiving interrupts that
-are bound to an SDEI event. However, there are cases where the Secure world
-requires dispatch of an SDEI event as a direct or indirect result of a past
-activity, such as receiving a Secure interrupt or an exception.
-
-The SDEI dispatcher implementation provides ``sdei_dispatch_event()`` API for
-this purpose. The API has the following signature:
-
-::
-
- int sdei_dispatch_event(int ev_num);
-
-The parameter ``ev_num`` is the event number to dispatch. The API returns ``0``
-on success, or ``-1`` on failure.
-
-The following figure depicts a scenario involving explicit dispatch of SDEI
-event. A commentary is provided below:
-
-.. image:: plantuml/sdei_explicit_dispatch.svg
-
-As part of initialisation, the SDEI client registers a handler for a platform
-event [1], enables the event [3], and unmasks the current PE [5]. Note that,
-unlike in `general SDEI dispatch`_, this doesn't involve interrupt binding, as
-bound or dynamic events can't be explicitly dispatched (see the section below).
-
-At a later point in time, a critical event [#critical-event]_ is trapped into
-EL3 [7]. EL3 performs a first-level triage of the event, and a RAS component
-assumes further handling [8]. The dispatch completes, but intends to involve
-Non-secure world in further handling, and therefore decides to explicitly
-dispatch an event [10] (which the client had already registered for [1]). The
-rest of the sequence is similar to that in the `general SDEI dispatch`_: the
-requested event is dispatched to the client (assuming all the conditions are
-met), and when the handler completes, the preempted execution resumes.
-
-.. [#critical-event] Examples of critical event are *SError*, *Synchronous
- External Abort*, *Fault Handling interrupt*, or *Error
- Recovery interrupt* from one of RAS nodes in the system.
-
-Conditions for event dispatch
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-All of the following requirements must be met for the API to return ``0`` and
-event to be dispatched:
-
-- SDEI events must be unmasked on the PE. I.e. the client must have called
- ``PE_UNMASK`` beforehand.
-
-- Event 0 can't be dispatched.
-
-- The event must be declared using the ``SDEI_EXPLICIT_EVENT()`` macro
- described above.
-
-- The event must be private to the PE.
-
-- The event must have been registered for and enabled.
-
-- A dispatch for the same event must not be outstanding. I.e. it hasn't already
- been dispatched and is yet to be completed.
-
-- The priority of the event (either Critical or Normal, as configured by the
- platform at build-time) shouldn't cause priority inversion. This means:
-
- - If it's of Normal priority, neither Normal nor Critical priority dispatch
- must be outstanding on the PE.
-
- - If it's of a Critical priority, no Critical priority dispatch must be
- outstanding on the PE.
-
-Further, the caller should be aware of the following assumptions made by the
-dispatcher:
-
-- The caller of the API is a component running in EL3; for example, a RAS
- driver.
-
-- The requested dispatch will be permitted by the Exception Handling Framework.
- I.e. the caller must make sure that the requested dispatch has sufficient
- priority so as not to cause priority level inversion within Exception
- Handling Framework.
-
-- The caller must be prepared for the SDEI dispatcher to restore the Non-secure
- context, and mark that the active context.
-
-- The call will block until the SDEI client completes the event (i.e. when the
- client calls either ``SDEI_EVENT_COMPLETE`` or ``SDEI_COMPLETE_AND_RESUME``).
-
-- The caller must be prepared for this API to return failure and handle
- accordingly.
-
-Porting requirements
---------------------
-
-The porting requirements of the SDEI dispatcher are outlined in the `porting
-guide`__.
-
-.. __: `SDEI porting requirements`_
-
-Note on writing SDEI event handlers
------------------------------------
-
-*This section pertains to SDEI event handlers in general, not just when using
-the TF-A SDEI dispatcher.*
-
-The SDEI specification requires that event handlers preserve the contents of all
-registers except ``x0`` to ``x17``. This has significance if event handler is
-written in C: compilers typically adjust the stack frame at the beginning and
-end of C functions. For example, AArch64 GCC typically produces the following
-function prologue and epilogue:
-
-::
-
- c_event_handler:
- stp x29, x30, [sp,#-32]!
- mov x29, sp
-
- ...
-
- bl ...
-
- ...
-
- ldp x29, x30, [sp],#32
- ret
-
-The register ``x29`` is used as frame pointer in the prologue. Because neither a
-valid ``SDEI_EVENT_COMPLETE`` nor ``SDEI_EVENT_COMPLETE_AND_RESUME`` calls
-return to the handler, the epilogue never gets executed, and registers ``x29``
-and ``x30`` (in the case above) are inadvertently corrupted. This violates the
-SDEI specification, and the normal execution thereafter will result in
-unexpected behaviour.
-
-To work this around, it's advised that the top-level event handlers are
-implemented in assembly, following a similar pattern as below:
-
-::
-
- asm_event_handler:
- /* Save link register whilst maintaining stack alignment */
- stp xzr, x30, [sp, #-16]!
- bl c_event_handler
-
- /* Restore link register */
- ldp xzr, x30, [sp], #16
-
- /* Complete call */
- ldr x0, =SDEI_EVENT_COMPLETE
- smc #0
- b .
-
-----
-
-*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
-.. _SDEI porting requirements: porting-guide.rst#sdei-porting-requirements
+++ /dev/null
-*******************************
-Secure Partition Manager Design
-*******************************
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-Background
-==========
-
-In some market segments that primarily deal with client-side devices like mobile
-phones, tablets, STBs and embedded devices, a Trusted OS instantiates trusted
-applications to provide security services like DRM, secure payment and
-authentication. The Global Platform TEE Client API specification defines the API
-used by Non-secure world applications to access these services. A Trusted OS
-fulfils the requirements of a security service as described above.
-
-Management services are typically implemented at the highest level of privilege
-in the system, i.e. EL3 in Trusted Firmware-A (TF-A). The service requirements are
-fulfilled by the execution environment provided by TF-A.
-
-The following diagram illustrates the corresponding software stack:
-
-|Image 1|
-
-In other market segments that primarily deal with server-side devices (e.g. data
-centres and enterprise servers) the secure software stack typically does not
-include a Global Platform Trusted OS. Security functions are accessed through
-other interfaces (e.g. ACPI TCG TPM interface, UEFI runtime variable service).
-
-Placement of management and security functions with diverse requirements in a
-privileged Exception Level (i.e. EL3 or S-EL1) makes security auditing of
-firmware more difficult and does not allow isolation of unrelated services from
-each other either.
-
-Introduction
-============
-
-A **Secure Partition** is a software execution environment instantiated in
-S-EL0 that can be used to implement simple management and security services.
-Since S-EL0 is an unprivileged Exception Level, a Secure Partition relies on
-privileged firmware (i.e. TF-A) to be granted access to system and processor
-resources. Essentially, it is a software sandbox in the Secure world that runs
-under the control of privileged software, provides one or more services and
-accesses the following system resources:
-
-- Memory and device regions in the system address map.
-
-- PE system registers.
-
-- A range of synchronous exceptions (e.g. SMC function identifiers).
-
-Note that currently TF-A only supports handling one Secure Partition.
-
-A Secure Partition enables TF-A to implement only the essential secure
-services in EL3 and instantiate the rest in a partition in S-EL0.
-Furthermore, multiple Secure Partitions can be used to isolate unrelated
-services from each other.
-
-The following diagram illustrates the place of a Secure Partition in a typical
-Armv8-A software stack. A single or multiple Secure Partitions provide secure
-services to software components in the Non-secure world and other Secure
-Partitions.
-
-|Image 2|
-
-The TF-A build system is responsible for including the Secure Partition image
-in the FIP. During boot, BL2 includes support to authenticate and load the
-Secure Partition image. A BL31 component called **Secure Partition Manager
-(SPM)** is responsible for managing the partition. This is semantically
-similar to a hypervisor managing a virtual machine.
-
-The SPM is responsible for the following actions during boot:
-
-- Allocate resources requested by the Secure Partition.
-
-- Perform architectural and system setup required by the Secure Partition to
- fulfil a service request.
-
-- Implement a standard interface that is used for initialising a Secure
- Partition.
-
-The SPM is responsible for the following actions during runtime:
-
-- Implement a standard interface that is used by a Secure Partition to fulfil
- service requests.
-
-- Implement a standard interface that is used by the Non-secure world for
- accessing the services exported by a Secure Partition. A service can be
- invoked through a SMC.
-
-Alternatively, a partition can be viewed as a thread of execution running under
-the control of the SPM. Hence common programming concepts described below are
-applicable to a partition.
-
-Description
-===========
-
-The previous section introduced some general aspects of the software
-architecture of a Secure Partition. This section describes the specific choices
-made in the current implementation of this software architecture. Subsequent
-revisions of the implementation will include a richer set of features that
-enable a more flexible architecture.
-
-Building TF-A with Secure Partition support
--------------------------------------------
-
-SPM is supported on the Arm FVP exclusively at the moment. The current
-implementation supports inclusion of only a single Secure Partition in which a
-service always runs to completion (e.g. the requested services cannot be
-preempted to give control back to the Normal world).
-
-It is not currently possible for BL31 to integrate SPM support and a Secure
-Payload Dispatcher (SPD) at the same time; they are mutually exclusive. In the
-SPM bootflow, a Secure Partition image executing at S-EL0 replaces the Secure
-Payload image executing at S-EL1 (e.g. a Trusted OS). Both are referred to as
-BL32.
-
-A working prototype of a SP has been implemented by re-purposing the EDK2 code
-and tools, leveraging the concept of the *Standalone Management Mode (MM)* in
-the UEFI specification (see the PI v1.6 Volume 4: Management Mode Core
-Interface). This will be referred to as the *Standalone MM Secure Partition* in
-the rest of this document.
-
-To enable SPM support in TF-A, the source code must be compiled with the build
-flag ``ENABLE_SPM=1``, along with ``EL3_EXCEPTION_HANDLING=1``. On Arm
-platforms the build option ``ARM_BL31_IN_DRAM`` must be set to 1. Also, the
-location of the binary that contains the BL32 image
-(``BL32=path/to/image.bin``) must be specified.
-
-First, build the Standalone MM Secure Partition. To build it, refer to the
-`instructions in the EDK2 repository`_.
-
-Then build TF-A with SPM support and include the Standalone MM Secure Partition
-image in the FIP:
-
-::
-
- BL32=path/to/standalone/mm/sp BL33=path/to/bl33.bin \
- make PLAT=fvp ENABLE_SPM=1 ARM_BL31_IN_DRAM=1 fip all
-
-Describing Secure Partition resources
--------------------------------------
-
-TF-A exports a porting interface that enables a platform to specify the system
-resources required by the Secure Partition. Some instructions are given below.
-However, this interface is under development and it may change as new features
-are implemented.
-
-- A Secure Partition is considered a BL32 image, so the same defines that apply
- to BL32 images apply to a Secure Partition: ``BL32_BASE`` and ``BL32_LIMIT``.
-
-- The following defines are needed to allocate space for the translation tables
- used by the Secure Partition: ``PLAT_SP_IMAGE_MMAP_REGIONS`` and
- ``PLAT_SP_IMAGE_MAX_XLAT_TABLES``.
-
-- The functions ``plat_get_secure_partition_mmap()`` and
- ``plat_get_secure_partition_boot_info()`` have to be implemented. The file
- ``plat/arm/board/fvp/fvp_common.c`` can be used as an example. It uses the
- defines in ``include/plat/arm/common/arm_spm_def.h``.
-
- - ``plat_get_secure_partition_mmap()`` returns an array of mmap regions that
- describe the memory regions that the SPM needs to allocate for a Secure
- Partition.
-
- - ``plat_get_secure_partition_boot_info()`` returns a
- ``secure_partition_boot_info_t`` struct that is populated by the platform
- with information about the memory map of the Secure Partition.
-
-For an example of all the changes in context, you may refer to commit
-``e29efeb1b4``, in which the port for FVP was introduced.
-
-Accessing Secure Partition services
------------------------------------
-
-The `SMC Calling Convention`_ (*Arm DEN 0028B*) describes SMCs as a conduit for
-accessing services implemented in the Secure world. The ``MM_COMMUNICATE``
-interface defined in the `Management Mode Interface Specification`_ (*Arm DEN
-0060A*) is used to invoke a Secure Partition service as a Fast Call.
-
-The mechanism used to identify a service within the partition depends on the
-service implementation. It is assumed that the caller of the service will be
-able to discover this mechanism through standard platform discovery mechanisms
-like ACPI and Device Trees. For example, *Volume 4: Platform Initialisation
-Specification v1.6. Management Mode Core Interface* specifies that a GUID is
-used to identify a management mode service. A client populates the GUID in the
-``EFI_MM_COMMUNICATE_HEADER``. The header is populated in the communication
-buffer shared with the Secure Partition.
-
-A Fast Call appears to be atomic from the perspective of the caller and returns
-when the requested operation has completed. A service invoked through the
-``MM_COMMUNICATE`` SMC will run to completion in the partition on a given CPU.
-The SPM is responsible for guaranteeing this behaviour. This means that there
-can only be a single outstanding Fast Call in a partition on a given CPU.
-
-Exchanging data with the Secure Partition
------------------------------------------
-
-The exchange of data between the Non-secure world and the partition takes place
-through a shared memory region. The location of data in the shared memory area
-is passed as a parameter to the ``MM_COMMUNICATE`` SMC. The shared memory area
-is statically allocated by the SPM and is expected to be either implicitly known
-to the Non-secure world or discovered through a platform discovery mechanism
-e.g. ACPI table or device tree. It is possible for the Non-secure world to
-exchange data with a partition only if it has been populated in this shared
-memory area. The shared memory area is implemented as per the guidelines
-specified in Section 3.2.3 of the `Management Mode Interface Specification`_
-(*Arm DEN 0060A*).
-
-The format of data structures used to encapsulate data in the shared memory is
-agreed between the Non-secure world and the Secure Partition. For example, in
-the `Management Mode Interface specification`_ (*Arm DEN 0060A*), Section 4
-describes that the communication buffer shared between the Non-secure world and
-the Management Mode (MM) in the Secure world must be of the type
-``EFI_MM_COMMUNICATE_HEADER``. This data structure is defined in *Volume 4:
-Platform Initialisation Specification v1.6. Management Mode Core Interface*.
-Any caller of a MM service will have to use the ``EFI_MM_COMMUNICATE_HEADER``
-data structure.
-
-Runtime model of the Secure Partition
-=====================================
-
-This section describes how the Secure Partition interfaces with the SPM.
-
-Interface with SPM
-------------------
-
-In order to instantiate one or more secure services in the Secure Partition in
-S-EL0, the SPM should define the following types of interfaces:
-
-- Interfaces that enable access to privileged operations from S-EL0. These
- operations typically require access to system resources that are either shared
- amongst multiple software components in the Secure world or cannot be directly
- accessed from an unprivileged Exception Level.
-
-- Interfaces that establish the control path between the SPM and the Secure
- Partition.
-
-This section describes the APIs currently exported by the SPM that enable a
-Secure Partition to initialise itself and export its services in S-EL0. These
-interfaces are not accessible from the Non-secure world.
-
-Conduit
-^^^^^^^
-
-The `SMC Calling Convention`_ (*Arm DEN 0028B*) specification describes the SMC
-and HVC conduits for accessing firmware services and their availability
-depending on the implemented Exception levels. In S-EL0, the Supervisor Call
-exception (SVC) is the only architectural mechanism available for unprivileged
-software to make a request for an operation implemented in privileged software.
-Hence, the SVC conduit must be used by the Secure Partition to access interfaces
-implemented by the SPM.
-
-A SVC causes an exception to be taken to S-EL1. TF-A assumes ownership of S-EL1
-and installs a simple exception vector table in S-EL1 that relays a SVC request
-from a Secure Partition as a SMC request to the SPM in EL3. Upon servicing the
-SMC request, Arm Trusted Firmware returns control directly to S-EL0 through an
-ERET instruction.
-
-Calling conventions
-^^^^^^^^^^^^^^^^^^^
-
-The `SMC Calling Convention`_ (*Arm DEN 0028B*) specification describes the
-32-bit and 64-bit calling conventions for the SMC and HVC conduits. The SVC
-conduit introduces the concept of SVC32 and SVC64 calling conventions. The SVC32
-and SVC64 calling conventions are equivalent to the 32-bit (SMC32) and the
-64-bit (SMC64) calling conventions respectively.
-
-Communication initiated by SPM
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-A service request is initiated from the SPM through an exception return
-instruction (ERET) to S-EL0. Later, the Secure Partition issues an SVC
-instruction to signal completion of the request. Some example use cases are
-given below:
-
-- A request to initialise the Secure Partition during system boot.
-
-- A request to handle a runtime service request.
-
-Communication initiated by Secure Partition
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-A request is initiated from the Secure Partition by executing a SVC instruction.
-An ERET instruction is used by TF-A to return to S-EL0 with the result of the
-request.
-
-For instance, a request to perform privileged operations on behalf of a
-partition (e.g. management of memory attributes in the translation tables for
-the Secure EL1&0 translation regime).
-
-Interfaces
-^^^^^^^^^^
-
-The current implementation reserves function IDs for Fast Calls in the Standard
-Secure Service calls range (see `SMC Calling Convention`_ (*Arm DEN 0028B*)
-specification) for each API exported by the SPM. This section defines the
-function prototypes for each function ID. The function IDs specify whether one
-or both of the SVC32 and SVC64 calling conventions can be used to invoke the
-corresponding interface.
-
-Secure Partition Event Management
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The Secure Partition provides an Event Management interface that is used by the
-SPM to delegate service requests to the Secure Partition. The interface also
-allows the Secure Partition to:
-
-- Register with the SPM a service that it provides.
-- Indicate completion of a service request delegated by the SPM
-
-Miscellaneous interfaces
-------------------------
-
-``SPM_VERSION_AARCH32``
-^^^^^^^^^^^^^^^^^^^^^^^
-
-- Description
-
- Returns the version of the interface exported by SPM.
-
-- Parameters
-
- - **uint32** - Function ID
-
- - SVC32 Version: **0x84000060**
-
-- Return parameters
-
- - **int32** - Status
-
- On success, the format of the value is as follows:
-
- - Bit [31]: Must be 0
- - Bits [30:16]: Major Version. Must be 0 for this revision of the SPM
- interface.
- - Bits [15:0]: Minor Version. Must be 1 for this revision of the SPM
- interface.
-
- On error, the format of the value is as follows:
-
- - ``NOT_SUPPORTED``: SPM interface is not supported or not available for the
- client.
-
-- Usage
-
- This function returns the version of the Secure Partition Manager
- implementation. The major version is 0 and the minor version is 1. The version
- number is a 31-bit unsigned integer, with the upper 15 bits denoting the major
- revision, and the lower 16 bits denoting the minor revision. The following
- rules apply to the version numbering:
-
- - Different major revision values indicate possibly incompatible functions.
-
- - For two revisions, A and B, for which the major revision values are
- identical, if the minor revision value of revision B is greater than the
- minor revision value of revision A, then every function in revision A must
- work in a compatible way with revision B. However, it is possible for
- revision B to have a higher function count than revision A.
-
-- Implementation responsibilities
-
- If this function returns a valid version number, all the functions that are
- described subsequently must be implemented, unless it is explicitly stated
- that a function is optional.
-
-See `Error Codes`_ for integer values that are associated with each return
-code.
-
-Secure Partition Initialisation
--------------------------------
-
-The SPM is responsible for initialising the architectural execution context to
-enable initialisation of a service in S-EL0. The responsibilities of the SPM are
-listed below. At the end of initialisation, the partition issues a
-``SP_EVENT_COMPLETE_AARCH64`` call (described later) to signal readiness for
-handling requests for services implemented by the Secure Partition. The
-initialisation event is executed as a Fast Call.
-
-Entry point invocation
-^^^^^^^^^^^^^^^^^^^^^^
-
-The entry point for service requests that should be handled as Fast Calls is
-used as the target of the ERET instruction to start initialisation of the Secure
-Partition.
-
-Architectural Setup
-^^^^^^^^^^^^^^^^^^^
-
-At cold boot, system registers accessible from S-EL0 will be in their reset
-state unless otherwise specified. The SPM will perform the following
-architectural setup to enable execution in S-EL0
-
-MMU setup
-^^^^^^^^^
-
-The platform port of a Secure Partition specifies to the SPM a list of regions
-that it needs access to and their attributes. The SPM validates this resource
-description and initialises the Secure EL1&0 translation regime as follows.
-
-1. Device regions are mapped with nGnRE attributes and Execute Never
- instruction access permissions.
-
-2. Code memory regions are mapped with RO data and Executable instruction access
- permissions.
-
-3. Read Only data memory regions are mapped with RO data and Execute Never
- instruction access permissions.
-
-4. Read Write data memory regions are mapped with RW data and Execute Never
- instruction access permissions.
-
-5. If the resource description does not explicitly describe the type of memory
- regions then all memory regions will be marked with Code memory region
- attributes.
-
-6. The ``UXN`` and ``PXN`` bits are set for regions that are not executable by
- S-EL0 or S-EL1.
-
-System Register Setup
-^^^^^^^^^^^^^^^^^^^^^
-
-System registers that influence software execution in S-EL0 are setup by the SPM
-as follows:
-
-1. ``SCTLR_EL1``
-
- - ``UCI=1``
- - ``EOE=0``
- - ``WXN=1``
- - ``nTWE=1``
- - ``nTWI=1``
- - ``UCT=1``
- - ``DZE=1``
- - ``I=1``
- - ``UMA=0``
- - ``SA0=1``
- - ``C=1``
- - ``A=1``
- - ``M=1``
-
-2. ``CPACR_EL1``
-
- - ``FPEN=b'11``
-
-3. ``PSTATE``
-
- - ``D,A,I,F=1``
- - ``CurrentEL=0`` (EL0)
- - ``SpSel=0`` (Thread mode)
- - ``NRW=0`` (AArch64)
-
-General Purpose Register Setup
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-SPM will invoke the entry point of a service by executing an ERET instruction.
-This transition into S-EL0 is special since it is not in response to a previous
-request through a SVC instruction. This is the first entry into S-EL0. The
-general purpose register usage at the time of entry will be as specified in the
-"Return State" column of Table 3-1 in Section 3.1 "Register use in AArch64 SMC
-calls" of the `SMC Calling Convention`_ (*Arm DEN 0028B*) specification. In
-addition, certain other restrictions will be applied as described below.
-
-1. ``SP_EL0``
-
- A non-zero value will indicate that the SPM has initialised the stack pointer
- for the current CPU.
-
- The value will be 0 otherwise.
-
-2. ``X4-X30``
-
- The values of these registers will be 0.
-
-3. ``X0-X3``
-
- Parameters passed by the SPM.
-
- - ``X0``: Virtual address of a buffer shared between EL3 and S-EL0. The
- buffer will be mapped in the Secure EL1&0 translation regime with read-only
- memory attributes described earlier.
-
- - ``X1``: Size of the buffer in bytes.
-
- - ``X2``: Cookie value (*IMPLEMENTATION DEFINED*).
-
- - ``X3``: Cookie value (*IMPLEMENTATION DEFINED*).
-
-Runtime Event Delegation
-------------------------
-
-The SPM receives requests for Secure Partition services through a synchronous
-invocation (i.e. a SMC from the Non-secure world). These requests are delegated
-to the partition by programming a return from the last
-``SP_EVENT_COMPLETE_AARCH64`` call received from the partition. The last call
-was made to signal either completion of Secure Partition initialisation or
-completion of a partition service request.
-
-``SP_EVENT_COMPLETE_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- Description
-
- Signal completion of the last SP service request.
-
-- Parameters
-
- - **uint32** - Function ID
-
- - SVC64 Version: **0xC4000061**
-
- - **int32** - Event Status Code
-
- Zero or a positive value indicates that the event was handled successfully.
- The values depend upon the original event that was delegated to the Secure
- partition. They are described as follows.
-
- - ``SUCCESS`` : Used to indicate that the Secure Partition was initialised
- or a runtime request was handled successfully.
-
- - Any other value greater than 0 is used to pass a specific Event Status
- code in response to a runtime event.
-
- A negative value indicates an error. The values of Event Status code depend
- on the original event.
-
-- Return parameters
-
- - **int32** - Event ID/Return Code
-
- Zero or a positive value specifies the unique ID of the event being
- delegated to the partition by the SPM.
-
- In the current implementation, this parameter contains the function ID of
- the ``MM_COMMUNICATE`` SMC. This value indicates to the partition that an
- event has been delegated to it in response to an ``MM_COMMUNICATE`` request
- from the Non-secure world.
-
- A negative value indicates an error. The format of the value is as follows:
-
- - ``NOT_SUPPORTED``: Function was called from the Non-secure world.
-
- See `Error Codes`_ for integer values that are associated with each return
- code.
-
- - **uint32** - Event Context Address
-
- Address of a buffer shared between the SPM and Secure Partition to pass
- event specific information. The format of the data populated in the buffer
- is implementation defined.
-
- The buffer is mapped in the Secure EL1&0 translation regime with read-only
- memory attributes described earlier.
-
- For the SVC64 version, this parameter is a 64-bit Virtual Address (VA).
-
- For the SVC32 version, this parameter is a 32-bit Virtual Address (VA).
-
- - **uint32** - Event context size
-
- Size of the memory starting at Event Address.
-
- - **uint32/uint64** - Event Cookie
-
- This is an optional parameter. If unused its value is SBZ.
-
-- Usage
-
- This function signals to the SPM that the handling of the last event delegated
- to a partition has completed. The partition is ready to handle its next event.
- A return from this function is in response to the next event that will be
- delegated to the partition. The return parameters describe the next event.
-
-- Caller responsibilities
-
- A Secure Partition must only call ``SP_EVENT_COMPLETE_AARCH64`` to signal
- completion of a request that was delegated to it by the SPM.
-
-- Callee responsibilities
-
- When the SPM receives this call from a Secure Partition, the corresponding
- syndrome information can be used to return control through an ERET
- instruction, to the instruction immediately after the call in the Secure
- Partition context. This syndrome information comprises of general purpose and
- system register values when the call was made.
-
- The SPM must save this syndrome information and use it to delegate the next
- event to the Secure Partition. The return parameters of this interface must
- specify the properties of the event and be populated in ``X0-X3/W0-W3``
- registers.
-
-Secure Partition Memory Management
-----------------------------------
-
-A Secure Partition executes at S-EL0, which is an unprivileged Exception Level.
-The SPM is responsible for enabling access to regions of memory in the system
-address map from a Secure Partition. This is done by mapping these regions in
-the Secure EL1&0 Translation regime with appropriate memory attributes.
-Attributes refer to memory type, permission, cacheability and shareability
-attributes used in the Translation tables. The definitions of these attributes
-and their usage can be found in the `Armv8-A ARM`_ (*Arm DDI 0487*).
-
-All memory required by the Secure Partition is allocated upfront in the SPM,
-even before handing over to the Secure Partition for the first time. The initial
-access permissions of the memory regions are statically provided by the platform
-port and should allow the Secure Partition to run its initialisation code.
-
-However, they might not suit the final needs of the Secure Partition because its
-final memory layout might not be known until the Secure Partition initialises
-itself. As the Secure Partition initialises its runtime environment it might,
-for example, load dynamically some modules. For instance, a Secure Partition
-could implement a loader for a standard executable file format (e.g. an PE-COFF
-loader for loading executable files at runtime). These executable files will be
-a part of the Secure Partition image. The location of various sections in an
-executable file and their permission attributes (e.g. read-write data, read-only
-data and code) will be known only when the file is loaded into memory.
-
-In this case, the Secure Partition needs a way to change the access permissions
-of its memory regions. The SPM provides this feature through the
-``SP_MEMORY_ATTRIBUTES_SET_AARCH64`` SVC interface. This interface is available
-to the Secure Partition during a specific time window: from the first entry into
-the Secure Partition up to the first ``SP_EVENT_COMPLETE`` call that signals the
-Secure Partition has finished its initialisation. Once the initialisation is
-complete, the SPM does not allow changes to the memory attributes.
-
-This section describes the standard SVC interface that is implemented by the SPM
-to determine and change permission attributes of memory regions that belong to a
-Secure Partition.
-
-``SP_MEMORY_ATTRIBUTES_GET_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- Description
-
- Request the permission attributes of a memory region from S-EL0.
-
-- Parameters
-
- - **uint32** Function ID
-
- - SVC64 Version: **0xC4000064**
-
- - **uint64** Base Address
-
- This parameter is a 64-bit Virtual Address (VA).
-
- There are no alignment restrictions on the Base Address. The permission
- attributes of the translation granule it lies in are returned.
-
-- Return parameters
-
- - **int32** - Memory Attributes/Return Code
-
- On success the format of the Return Code is as follows:
-
- - Bits[1:0] : Data access permission
-
- - b'00 : No access
- - b'01 : Read-Write access
- - b'10 : Reserved
- - b'11 : Read-only access
-
- - Bit[2]: Instruction access permission
-
- - b'0 : Executable
- - b'1 : Non-executable
-
- - Bit[30:3] : Reserved. SBZ.
-
- - Bit[31] : Must be 0
-
- On failure the following error codes are returned:
-
- - ``INVALID_PARAMETERS``: The Secure Partition is not allowed to access the
- memory region the Base Address lies in.
-
- - ``NOT_SUPPORTED`` : The SPM does not support retrieval of attributes of
- any memory page that is accessible by the Secure Partition, or the
- function was called from the Non-secure world. Also returned if it is
- used after ``SP_EVENT_COMPLETE_AARCH64``.
-
- See `Error Codes`_ for integer values that are associated with each return
- code.
-
-- Usage
-
- This function is used to request the permission attributes for S-EL0 on a
- memory region accessible from a Secure Partition. The size of the memory
- region is equal to the Translation Granule size used in the Secure EL1&0
- translation regime. Requests to retrieve other memory region attributes are
- not currently supported.
-
-- Caller responsibilities
-
- The caller must obtain the Translation Granule Size of the Secure EL1&0
- translation regime from the SPM through an implementation defined method.
-
-- Callee responsibilities
-
- The SPM must not return the memory access controls for a page of memory that
- is not accessible from a Secure Partition.
-
-``SP_MEMORY_ATTRIBUTES_SET_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- Description
-
- Set the permission attributes of a memory region from S-EL0.
-
-- Parameters
-
- - **uint32** - Function ID
-
- - SVC64 Version: **0xC4000065**
-
- - **uint64** - Base Address
-
- This parameter is a 64-bit Virtual Address (VA).
-
- The alignment of the Base Address must be greater than or equal to the size
- of the Translation Granule Size used in the Secure EL1&0 translation
- regime.
-
- - **uint32** - Page count
-
- Number of pages starting from the Base Address whose memory attributes
- should be changed. The page size is equal to the Translation Granule Size.
-
- - **uint32** - Memory Access Controls
-
- - Bits[1:0] : Data access permission
-
- - b'00 : No access
- - b'01 : Read-Write access
- - b'10 : Reserved
- - b'11 : Read-only access
-
- - Bit[2] : Instruction access permission
-
- - b'0 : Executable
- - b'1 : Non-executable
-
- - Bits[31:3] : Reserved. SBZ.
-
- A combination of attributes that mark the region with RW and Executable
- permissions is prohibited. A request to mark a device memory region with
- Executable permissions is prohibited.
-
-- Return parameters
-
- - **int32** - Return Code
-
- - ``SUCCESS``: The Memory Access Controls were changed successfully.
-
- - ``DENIED``: The SPM is servicing a request to change the attributes of a
- memory region that overlaps with the region specified in this request.
-
- - ``INVALID_PARAMETER``: An invalid combination of Memory Access Controls
- has been specified. The Base Address is not correctly aligned. The Secure
- Partition is not allowed to access part or all of the memory region
- specified in the call.
-
- - ``NO_MEMORY``: The SPM does not have memory resources to change the
- attributes of the memory region in the translation tables.
-
- - ``NOT_SUPPORTED``: The SPM does not permit change of attributes of any
- memory region that is accessible by the Secure Partition. Function was
- called from the Non-secure world. Also returned if it is used after
- ``SP_EVENT_COMPLETE_AARCH64``.
-
- See `Error Codes`_ for integer values that are associated with each return
- code.
-
-- Usage
-
- This function is used to change the permission attributes for S-EL0 on a
- memory region accessible from a Secure Partition. The size of the memory
- region is equal to the Translation Granule size used in the Secure EL1&0
- translation regime. Requests to change other memory region attributes are not
- currently supported.
-
- This function is only available at boot time. This interface is revoked after
- the Secure Partition sends the first ``SP_EVENT_COMPLETE_AARCH64`` to signal
- that it is initialised and ready to receive run-time requests.
-
-- Caller responsibilities
-
- The caller must obtain the Translation Granule Size of the Secure EL1&0
- translation regime from the SPM through an implementation defined method.
-
-- Callee responsibilities
-
- The SPM must preserve the original memory access controls of the region of
- memory in case of an unsuccessful call. The SPM must preserve the consistency
- of the S-EL1 translation regime if this function is called on different PEs
- concurrently and the memory regions specified overlap.
-
-Error Codes
------------
-
-.. csv-table::
- :header: "Name", "Value"
-
- ``SUCCESS``,0
- ``NOT_SUPPORTED``,-1
- ``INVALID_PARAMETER``,-2
- ``DENIED``,-3
- ``NO_MEMORY``,-5
- ``NOT_PRESENT``,-7
-
---------------
-
-*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _Armv8-A ARM: https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile
-.. _instructions in the EDK2 repository: https://github.com/tianocore/edk2-staging/blob/AArch64StandaloneMm/HowtoBuild.MD
-.. _Management Mode Interface Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0060a/DEN0060A_ARM_MM_Interface_Specification.pdf
-.. _SDEI Specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
-.. _SMC Calling Convention: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
-
-.. |Image 1| image:: diagrams/secure_sw_stack_tos.png
-.. |Image 2| image:: diagrams/secure_sw_stack_sp.png
+++ /dev/null
-Security Center
-===============
-
-Security Disclosures
---------------------
-
-We disclose all security vulnerabilities we find or are advised about that are
-relevant for ARM Trusted Firmware (TF). We encourage responsible disclosure of
-vulnerabilities and inform users as best we can about all possible issues.
-
-We disclose TF vulnerabilities as Security Advisories. These are listed at the
-bottom of this page and announced as issues in the `GitHub issue tracker`_ with
-the "security-advisory" tag. You can receive notification emails for these by
-watching that project.
-
-Found a Security Issue?
------------------------
-
-Although we try to keep TF secure, we can only do so with the help of the
-community of developers and security researchers.
-
-If you think you have found a security vulnerability, please *do not* report it
-in the `GitHub issue tracker`_. Instead send an email to
-
-Please include:
-
-* Trusted Firmware version (or commit) affected
-
-* A description of the concern or vulnerability
-
-* Details on how to replicate the vulnerability, including:
-
- - Configuration details
-
- - Proof of concept exploit code
-
- - Any additional software or tools required
-
-We recommend using `this PGP/GPG key`_ for encrypting the information. This key
-is also available at http://keyserver.pgp.com and LDAP port 389 of the same
-server. The fingerprint for this key is:
-
-::
-
- 1309 2C19 22B4 8E87 F17B FE5C 3AB7 EFCB 45A0 DFD0
-
-If you would like replies to be encrypted, please provide your public key.
-
-Please give us the time to respond to you and fix the vulnerability before going
-public. We do our best to respond and fix any issues quickly. We also need to
-ensure providers of products that use TF have a chance to consider the
-implications of the vulnerability and its remedy.
-
-Afterwards, we encourage you to write-up your findings about the TF source code.
-
-Attribution
------------
-
-We will name and thank you in the ``change-log.rst`` distributed with the source
-code and in any published security advisory.
-
-Security Advisories
--------------------
-
-+-----------+------------------------------------------------------------------+
-| ID | Title |
-+===========+==================================================================+
-| `TFV-1`_ | Malformed Firmware Update SMC can result in copy of unexpectedly |
-| | large data into secure memory |
-+-----------+------------------------------------------------------------------+
-| `TFV-2`_ | Enabled secure self-hosted invasive debug interface can allow |
-| | normal world to panic secure world |
-+-----------+------------------------------------------------------------------+
-| `TFV-3`_ | RO memory is always executable at AArch64 Secure EL1 |
-+-----------+------------------------------------------------------------------+
-| `TFV-4`_ | Malformed Firmware Update SMC can result in copy or |
-| | authentication of unexpected data in secure memory in AArch32 |
-| | state |
-+-----------+------------------------------------------------------------------+
-| `TFV-5`_ | Not initializing or saving/restoring PMCR_EL0 can leak secure |
-| | world timing information |
-+-----------+------------------------------------------------------------------+
-| `TFV-6`_ | Arm Trusted Firmware exposure to speculative processor |
-| | vulnerabilities using cache timing side-channels |
-+-----------+------------------------------------------------------------------+
-| `TFV-7`_ | Trusted Firmware-A exposure to cache speculation vulnerability |
-| | Variant 4 |
-+-----------+------------------------------------------------------------------+
-| `TFV-8`_ | Not saving x0 to x3 registers can leak information from one |
-| | Normal World SMC client to another |
-+-----------+------------------------------------------------------------------+
-
-.. _GitHub issue tracker: https://github.com/ARM-software/tf-issues/issues
-.. _this PGP/GPG key: security-reporting.asc
-.. _TFV-1: ./security_advisories/security-advisory-tfv-1.rst
-.. _TFV-2: ./security_advisories/security-advisory-tfv-2.rst
-.. _TFV-3: ./security_advisories/security-advisory-tfv-3.rst
-.. _TFV-4: ./security_advisories/security-advisory-tfv-4.rst
-.. _TFV-5: ./security_advisories/security-advisory-tfv-5.rst
-.. _TFV-6: ./security_advisories/security-advisory-tfv-6.rst
-.. _TFV-7: ./security_advisories/security-advisory-tfv-7.rst
-.. _TFV-8: ./security_advisories/security-advisory-tfv-8.rst
+++ /dev/null
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: PGP Desktop 10.2.0 (Build 2317)
-
-mQENBFey/QMBCACyxJaLsMYU794ZfzLdY172tHXRJfP0X3b34HU35G7kYl1zNiYc
-/NoygtQdtDv/aW1B2A/YTNhGge+gX4BWAREd5CYDbdPEoMWC395/qbnmMmez7YNY
-PEJ9Iq9e5AayAWwZTL1zgKwdvE+WTwWok/nMbsifJSEdhdrOIHNqRcZgplUUyZ2R
-sDqFtSbACO3xj4Psk8KJ23Ax7UZgULouZOJaHOnyq8F9V/U7zWvX4Odf96XaC1Em
-cUTsG0kQfa7Y4Hqqjzowq366I4k2o2LAtuLPWNCvq5jjEceLs2+qV4cNLgyL2dzO
-wtUL6EdkrGfkxsPHpsVKXig4wjeX9ehCSqRlABEBAAG0PVRydXN0ZWQgRmlybXdh
-cmUgU2VjdXJpdHkgPHRydXN0ZWQtZmlybXdhcmUtc2VjdXJpdHlAYXJtLmNvbT6J
-AYwEEAECAHYFAley/SEwFIAAAAAAIAAHcHJlZmVycmVkLWVtYWlsLWVuY29kaW5n
-QHBncC5jb21wZ3BtaW1lCAsJCAcDAgEKAhkBGRhsZGFwOi8va2V5c2VydmVyLnBn
-cC5jb20FGwMAAAAFFgADAgEFHgEAAAAGFQgJCgMCAAoJEDq378tFoN/QFJsH/0ly
-H91LYYzKIQrbolQw7Rp47lgzH88uN1rInYpW2GaTbjwPffAhYJ4VsN8RaiFskD9m
-DjMg4vY8p0jPTCUX1Acq20Wq0Ybv3HcrtjUp4ie0+rLUi3043yJyKFMWkJC2Kr+p
-SobnxSrAie4HDFUgSaPoh9Qf1zXEzOavdgcziMiyS5iVUf6NXYZ9z82OTZ6TdPKS
-u+L5zOHTdrV3+hD54w00Xa+EIE7u4v0to6Uwm977508hyGuvpOVq+u7+S3qJQvnY
-+JheStbgLsm6CyoRjyrlTE01ujAD6hI6Ef9yMgEljOBEy4phKAJ67SCRLEOiCp5U
-YHFCULwhzIyg2y3WmZSJASIEEAECAAwFAlezAnwFAwASdQAACgkQlxC4m8pXrXzd
-GAf/T8YEICI9qQt2vnCtCbBvVaTc2sAphVZ51kZVDqCDPB7znDtJYRBpi/9IPELt
-mYwIElMx2mqmahVaeUghmbzmcLZe8QHUi8GanO1mh+ook6uyjRojSIq6VUVV5uUf
-tuscfhpilOvUclqMqYEIgXfl08YwS40Kmmj0qokwad0co0zGQ8GEhlgMi2yvJfiG
-fPS0Xcn1J0980E/VgJQCAKwZvukrbb32WVwuhgepqs/4/62PZNxglcErioFt6P0A
-ik4t9Hr0uErqCeEKiYtmEw5e9ioRdX7CV+tJgIk907Tpv6E0iDFRJHmJBvmsz82O
-stOazS3wZ5Xck7asTqkvoyo9Z7kBDQRXsv0DAQgAsmL1UUIWyoNmYJWixSPDmclP
-0ul3T1FCOsIlWTeVeshnHByYdgZOfce78ETCUoq8G7qvYm4GRrEDpqVbxqTxJioP
-4Li05WDdNCKzSoqWd8ADA48gYnnJEu2NhA7ZkEC6u3+Mdbmd3M0J6nsAWeE0BV1p
-F5zI600sJuoH2QNWB7Kv5N3GCFE4IgCIH8MwDo4Y4FTZtygx4GjEtSExiOIz+bpX
-2+GkFCQGpIyLHLP4FmQmrsNzsIdEyFuG0IdoVuQ2PtNLiw+Wkm7CXWgRmFx/dtPN
-eVnOFWdbTtjBWVv/Z6zbANos2knfc75KR4FCQ6pWRvVeJuMuMopUDkfFDMtR8QAR
-AQABiQJBBBgBAgErBQJXsv0EBRsMAAAAwF0gBBkBCAAGBQJXsv0DAAoJENaB8ph8
-s9hu/nsH/Rx696ZR+1vZi5qCTUwo6s0Qa15x4OuyJEM85VgMLVY7/MZpp1Y8If6u
-A5BynQpy4QIPxIRsRx6twduW9/gb8UVhpMRPyuJ+5sSv0/KeUqkPbKSUGro2zGlR
-sjqPrchi6uafWZqOR/y/DNkEvkgZZaP+f9xs2qWKuoF08yTioo76QoroA4DVuVAT
-MkDFe9d3natAmfmjO4kvxuthg3y7R+sdXrCHpYYJZdbiR6gyj7e8whlSLwHQT3lz
-7QBL/CvVvL/dmhu5pk8fsksbehepMQTkCJ6GGEamOPEhwh7IvlzhEt97U4uzjuMd
-BPjqOCes+4QTmn/+lMTySG0kXxnHOEUACgkQOrfvy0Wg39D8Jgf/Uf3epkMOJ9xm
-N1l5vW8tQQ6RR055YQxQ9P6JMyCQGEJmGOcvrasCho69wMQDy4AYVtJaZd25LH/3
-LX/lcyDOP4C9VYXM+IxlcaRmjBKqWx9UzQeeioIkfmjMpJFU846ZP1dacge0lPx8
-p6ocPbM0rkv0xuF/dwkDQd4BPSmv4/3/UM8FRoYo8Q7SHkDR98wJ8FCm6k9wRtWC
-K/jzmBswY2TewAHom3jLzTM0FZ/n5Sini3EGAI2EvnQrxWRpeE7ZOkHKqLHEOaHl
-zeST4U/cUgxhwgnhbGJ7zmrFsHpYnnZYM3mIKfQ3/EhksZ68TF9IB1tfUiQTij4r
-9jWa0ybRdQ==
-=nZZb
------END PGP PUBLIC KEY BLOCK-----
--- /dev/null
+Security Advisories
+===================
+
+.. toctree::
+ :maxdepth: 1
+ :caption: Contents
+ :numbered:
+
+ security-advisory-tfv-1.rst
+ security-advisory-tfv-2.rst
+ security-advisory-tfv-3.rst
+ security-advisory-tfv-4.rst
+ security-advisory-tfv-5.rst
+ security-advisory-tfv-6.rst
+ security-advisory-tfv-7.rst
+ security-advisory-tfv-8.rst
+++ /dev/null
-OP-TEE Dispatcher
-=================
-
-`OP-TEE OS`_ is a Trusted OS running as Secure EL1.
-
-To build and execute OP-TEE follow the instructions at
-`OP-TEE build.git`_
-
---------------
-
-*Copyright (c) 2014-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _OP-TEE OS: https://github.com/OP-TEE/build
-.. _OP-TEE build.git: https://github.com/OP-TEE/build
+++ /dev/null
-Trusted Little Kernel (TLK) Dispatcher
-======================================
-
-TLK dispatcher (TLK-D) adds support for NVIDIA's Trusted Little Kernel (TLK)
-to work with Trusted Firmware-A (TF-A). TLK-D can be compiled by including it
-in the platform's makefile. TLK is primarily meant to work with Tegra SoCs,
-so while TF-A only supports TLK on Tegra, the dispatcher code can only be
-compiled for other platforms.
-
-In order to compile TLK-D, we need a BL32 image to be present. Since, TLKD
-just needs to compile, any BL32 image would do. To use TLK as the BL32, please
-refer to the "Build TLK" section.
-
-Once a BL32 is ready, TLKD can be included in the image by adding "SPD=tlkd"
-to the build command.
-
-Trusted Little Kernel (TLK)
-===========================
-
-TLK is a Trusted OS running as Secure EL1. It is a Free Open Source Software
-(FOSS) release of the NVIDIA® Trusted Little Kernel (TLK) technology, which
-extends technology made available with the development of the Little Kernel (LK).
-You can download the LK modular embedded preemptive kernel for use on Arm,
-x86, and AVR32 systems from https://github.com/travisg/lk
-
-NVIDIA implemented its Trusted Little Kernel (TLK) technology, designed as a
-free and open-source trusted execution environment (OTE).
-
-TLK features include:
-
-• Small, pre-emptive kernel
-• Supports multi-threading, IPCs, and thread scheduling
-• Added TrustZone features
-• Added Secure Storage
-• Under MIT/FreeBSD license
-
-NVIDIA extensions to Little Kernel (LK) include:
-
-• User mode
-• Address-space separation for TAs
-• TLK Client Application (CA) library
-• TLK TA library
-• Crypto library (encrypt/decrypt, key handling) via OpenSSL
-• Linux kernel driver
-• Cortex A9/A15 support
-• Power Management
-• TrustZone memory carve-out (reconfigurable)
-• Page table management
-• Debugging support over UART (USB planned)
-
-TLK is hosted by NVIDIA on http://nv-tegra.nvidia.com under the
-3rdparty/ote\_partner/tlk.git repository. Detailed information about
-TLK and OTE can be found in the Tegra\_BSP\_for\_Android\_TLK\_FOSS\_Reference.pdf
-manual located under the "documentation" directory\_.
-
-Build TLK
-=========
-
-To build and execute TLK, follow the instructions from "Building a TLK Device"
-section from Tegra\_BSP\_for\_Android\_TLK\_FOSS\_Reference.pdf manual.
-
-Input parameters to TLK
-=======================
-
-TLK expects the TZDRAM size and a structure containing the boot arguments. BL2
-passes this information to the EL3 software as members of the bl32\_ep\_info
-struct, where bl32\_ep\_info is part of bl31\_params\_t (passed by BL2 in X0)
-
-Example:
---------
-
-::
-
- bl32_ep_info->args.arg0 = TZDRAM size available for BL32
- bl32_ep_info->args.arg1 = unused (used only on Armv7-A)
- bl32_ep_info->args.arg2 = pointer to boot args
+++ /dev/null
-Trusty Dispatcher
-=================
-
-Trusty is a a set of software components, supporting a Trusted Execution
-Environment (TEE) on mobile devices, published and maintained by Google.
-
-Detailed information and build instructions can be found on the Android
-Open Source Project (AOSP) webpage for Trusty hosted at
-https://source.android.com/security/trusty
-
-Boot parameters
-===============
-
-Custom boot parameters can be passed to Trusty by providing a platform
-specific function:
-
-.. code:: c
-
- void plat_trusty_set_boot_args(aapcs64_params_t *args)
-
-If this function is provided ``args->arg0`` must be set to the memory
-size allocated to trusty. If the platform does not provide this
-function, but defines ``TSP_SEC_MEM_SIZE``, a default implementation
-will pass the memory size from ``TSP_SEC_MEM_SIZE``. ``args->arg1``
-can be set to a platform specific parameter block, and ``args->arg2``
-should then be set to the size of that block.
-
-Supported platforms
-===================
-
-Out of all the platforms supported by Trusted Firmware-A, Trusty is only
-verified and supported by NVIDIA's Tegra SoCs.
+++ /dev/null
-Trusted Board Boot Design Guide
-===============================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-The Trusted Board Boot (TBB) feature prevents malicious firmware from running on
-the platform by authenticating all firmware images up to and including the
-normal world bootloader. It does this by establishing a Chain of Trust using
-Public-Key-Cryptography Standards (PKCS).
-
-This document describes the design of Trusted Firmware-A (TF-A) TBB, which is an
-implementation of the `Trusted Board Boot Requirements (TBBR)`_ specification,
-Arm DEN0006D. It should be used in conjunction with the `Firmware Update`_
-design document, which implements a specific aspect of the TBBR.
-
-Chain of Trust
---------------
-
-A Chain of Trust (CoT) starts with a set of implicitly trusted components. On
-the Arm development platforms, these components are:
-
-- A SHA-256 hash of the Root of Trust Public Key (ROTPK). It is stored in the
- trusted root-key storage registers.
-
-- The BL1 image, on the assumption that it resides in ROM so cannot be
- tampered with.
-
-The remaining components in the CoT are either certificates or boot loader
-images. The certificates follow the `X.509 v3`_ standard. This standard
-enables adding custom extensions to the certificates, which are used to store
-essential information to establish the CoT.
-
-In the TBB CoT all certificates are self-signed. There is no need for a
-Certificate Authority (CA) because the CoT is not established by verifying the
-validity of a certificate's issuer but by the content of the certificate
-extensions. To sign the certificates, the PKCS#1 SHA-256 with RSA Encryption
-signature scheme is used with a RSA key length of 2048 bits. Future version of
-TF-A will support additional cryptographic algorithms.
-
-The certificates are categorised as "Key" and "Content" certificates. Key
-certificates are used to verify public keys which have been used to sign content
-certificates. Content certificates are used to store the hash of a boot loader
-image. An image can be authenticated by calculating its hash and matching it
-with the hash extracted from the content certificate. The SHA-256 function is
-used to calculate all hashes. The public keys and hashes are included as
-non-standard extension fields in the `X.509 v3`_ certificates.
-
-The keys used to establish the CoT are:
-
-- **Root of trust key**
-
- The private part of this key is used to sign the BL2 content certificate and
- the trusted key certificate. The public part is the ROTPK.
-
-- **Trusted world key**
-
- The private part is used to sign the key certificates corresponding to the
- secure world images (SCP_BL2, BL31 and BL32). The public part is stored in
- one of the extension fields in the trusted world certificate.
-
-- **Non-trusted world key**
-
- The private part is used to sign the key certificate corresponding to the
- non secure world image (BL33). The public part is stored in one of the
- extension fields in the trusted world certificate.
-
-- **BL3-X keys**
-
- For each of SCP_BL2, BL31, BL32 and BL33, the private part is used to
- sign the content certificate for the BL3-X image. The public part is stored
- in one of the extension fields in the corresponding key certificate.
-
-The following images are included in the CoT:
-
-- BL1
-- BL2
-- SCP_BL2 (optional)
-- BL31
-- BL33
-- BL32 (optional)
-
-The following certificates are used to authenticate the images.
-
-- **BL2 content certificate**
-
- It is self-signed with the private part of the ROT key. It contains a hash
- of the BL2 image.
-
-- **Trusted key certificate**
-
- It is self-signed with the private part of the ROT key. It contains the
- public part of the trusted world key and the public part of the non-trusted
- world key.
-
-- **SCP_BL2 key certificate**
-
- It is self-signed with the trusted world key. It contains the public part of
- the SCP_BL2 key.
-
-- **SCP_BL2 content certificate**
-
- It is self-signed with the SCP_BL2 key. It contains a hash of the SCP_BL2
- image.
-
-- **BL31 key certificate**
-
- It is self-signed with the trusted world key. It contains the public part of
- the BL31 key.
-
-- **BL31 content certificate**
-
- It is self-signed with the BL31 key. It contains a hash of the BL31 image.
-
-- **BL32 key certificate**
-
- It is self-signed with the trusted world key. It contains the public part of
- the BL32 key.
-
-- **BL32 content certificate**
-
- It is self-signed with the BL32 key. It contains a hash of the BL32 image.
-
-- **BL33 key certificate**
-
- It is self-signed with the non-trusted world key. It contains the public
- part of the BL33 key.
-
-- **BL33 content certificate**
-
- It is self-signed with the BL33 key. It contains a hash of the BL33 image.
-
-The SCP_BL2 and BL32 certificates are optional, but they must be present if the
-corresponding SCP_BL2 or BL32 images are present.
-
-Trusted Board Boot Sequence
----------------------------
-
-The CoT is verified through the following sequence of steps. The system panics
-if any of the steps fail.
-
-- BL1 loads and verifies the BL2 content certificate. The issuer public key is
- read from the verified certificate. A hash of that key is calculated and
- compared with the hash of the ROTPK read from the trusted root-key storage
- registers. If they match, the BL2 hash is read from the certificate.
-
- Note: the matching operation is platform specific and is currently
- unimplemented on the Arm development platforms.
-
-- BL1 loads the BL2 image. Its hash is calculated and compared with the hash
- read from the certificate. Control is transferred to the BL2 image if all
- the comparisons succeed.
-
-- BL2 loads and verifies the trusted key certificate. The issuer public key is
- read from the verified certificate. A hash of that key is calculated and
- compared with the hash of the ROTPK read from the trusted root-key storage
- registers. If the comparison succeeds, BL2 reads and saves the trusted and
- non-trusted world public keys from the verified certificate.
-
-The next two steps are executed for each of the SCP_BL2, BL31 & BL32 images.
-The steps for the optional SCP_BL2 and BL32 images are skipped if these images
-are not present.
-
-- BL2 loads and verifies the BL3x key certificate. The certificate signature
- is verified using the trusted world public key. If the signature
- verification succeeds, BL2 reads and saves the BL3x public key from the
- certificate.
-
-- BL2 loads and verifies the BL3x content certificate. The signature is
- verified using the BL3x public key. If the signature verification succeeds,
- BL2 reads and saves the BL3x image hash from the certificate.
-
-The next two steps are executed only for the BL33 image.
-
-- BL2 loads and verifies the BL33 key certificate. If the signature
- verification succeeds, BL2 reads and saves the BL33 public key from the
- certificate.
-
-- BL2 loads and verifies the BL33 content certificate. If the signature
- verification succeeds, BL2 reads and saves the BL33 image hash from the
- certificate.
-
-The next step is executed for all the boot loader images.
-
-- BL2 calculates the hash of each image. It compares it with the hash obtained
- from the corresponding content certificate. The image authentication succeeds
- if the hashes match.
-
-The Trusted Board Boot implementation spans both generic and platform-specific
-BL1 and BL2 code, and in tool code on the host build machine. The feature is
-enabled through use of specific build flags as described in the `User Guide`_.
-
-On the host machine, a tool generates the certificates, which are included in
-the FIP along with the boot loader images. These certificates are loaded in
-Trusted SRAM using the IO storage framework. They are then verified by an
-Authentication module included in TF-A.
-
-The mechanism used for generating the FIP and the Authentication module are
-described in the following sections.
-
-Authentication Framework
-------------------------
-
-The authentication framework included in TF-A provides support to implement
-the desired trusted boot sequence. Arm platforms use this framework to
-implement the boot requirements specified in the `TBBR-client`_ document.
-
-More information about the authentication framework can be found in the
-`Auth Framework`_ document.
-
-Certificate Generation Tool
----------------------------
-
-The ``cert_create`` tool is built and runs on the host machine as part of the
-TF-A build process when ``GENERATE_COT=1``. It takes the boot loader images
-and keys as inputs (keys must be in PEM format) and generates the
-certificates (in DER format) required to establish the CoT. New keys can be
-generated by the tool in case they are not provided. The certificates are then
-passed as inputs to the ``fiptool`` utility for creating the FIP.
-
-The certificates are also stored individually in the in the output build
-directory.
-
-The tool resides in the ``tools/cert_create`` directory. It uses OpenSSL SSL
-library version 1.0.1 or later to generate the X.509 certificates. Instructions
-for building and using the tool can be found in the `User Guide`_.
-
---------------
-
-*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _Firmware Update: firmware-update.rst
-.. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt
-.. _User Guide: user-guide.rst
-.. _Auth Framework: auth-framework.rst
-.. _TBBR-client: https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a
-.. _Trusted Board Boot Requirements (TBBR): `TBBR-client`_
+++ /dev/null
-Trusted Firmware-A User Guide
-=============================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-This document describes how to build Trusted Firmware-A (TF-A) and run it with a
-tested set of other software components using defined configurations on the Juno
-Arm development platform and Arm Fixed Virtual Platform (FVP) models. It is
-possible to use other software components, configurations and platforms but that
-is outside the scope of this document.
-
-This document assumes that the reader has previous experience running a fully
-bootable Linux software stack on Juno or FVP using the prebuilt binaries and
-filesystems provided by `Linaro`_. Further information may be found in the
-`Linaro instructions`_. It also assumes that the user understands the role of
-the different software components required to boot a Linux system:
-
-- Specific firmware images required by the platform (e.g. SCP firmware on Juno)
-- Normal world bootloader (e.g. UEFI or U-Boot)
-- Device tree
-- Linux kernel image
-- Root filesystem
-
-This document also assumes that the user is familiar with the `FVP models`_ and
-the different command line options available to launch the model.
-
-This document should be used in conjunction with the `Firmware Design`_.
-
-Host machine requirements
--------------------------
-
-The minimum recommended machine specification for building the software and
-running the FVP models is a dual-core processor running at 2GHz with 12GB of
-RAM. For best performance, use a machine with a quad-core processor running at
-2.6GHz with 16GB of RAM.
-
-The software has been tested on Ubuntu 16.04 LTS (64-bit). Packages used for
-building the software were installed from that distribution unless otherwise
-specified.
-
-The software has also been built on Windows 7 Enterprise SP1, using CMD.EXE,
-Cygwin, and Msys (MinGW) shells, using version 5.3.1 of the GNU toolchain.
-
-Tools
------
-
-Install the required packages to build TF-A with the following command:
-
-::
-
- sudo apt-get install device-tree-compiler build-essential gcc make git libssl-dev
-
-TF-A has been tested with Linaro Release 18.04.
-
-Download and install the AArch32 or AArch64 little-endian GCC cross compiler. If
-you would like to use the latest features available, download GCC 8.2-2019.01
-compiler from `arm Developer page`_. Otherwise, the `Linaro Release Notes`_
-documents which version of the compiler to use for a given Linaro Release. Also,
-these `Linaro instructions`_ provide further guidance and a script, which can be
-used to download Linaro deliverables automatically.
-
-Optionally, TF-A can be built using clang version 4.0 or newer or Arm
-Compiler 6. See instructions below on how to switch the default compiler.
-
-In addition, the following optional packages and tools may be needed:
-
-- ``device-tree-compiler`` (dtc) package if you need to rebuild the Flattened Device
- Tree (FDT) source files (``.dts`` files) provided with this software. The
- version of dtc must be 1.4.6 or above.
-
-- For debugging, Arm `Development Studio 5 (DS-5)`_.
-
-- To create and modify the diagram files included in the documentation, `Dia`_.
- This tool can be found in most Linux distributions. Inkscape is needed to
- generate the actual \*.png files.
-
-Getting the TF-A source code
-----------------------------
-
-Clone the repository from the Gerrit server. The project details may be found
-on the `arm-trusted-firmware-a project page`_. We recommend the "`Clone with
-commit-msg hook`" clone method, which will setup the git commit hook that
-automatically generates and inserts appropriate `Change-Id:` lines in your
-commit messages.
-
-Checking source code style
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Trusted Firmware follows the `Linux Coding Style`_ . When making changes to the
-source, for submission to the project, the source must be in compliance with
-this style guide.
-
-Additional, project-specific guidelines are defined in the `Trusted Firmware-A
-Coding Guidelines`_ document.
-
-To assist with coding style compliance, the project Makefile contains two
-targets which both utilise the `checkpatch.pl` script that ships with the Linux
-source tree. The project also defines certain *checkpatch* options in the
-``.checkpatch.conf`` file in the top-level directory.
-
-**Note:** Checkpatch errors will gate upstream merging of pull requests.
-Checkpatch warnings will not gate merging but should be reviewed and fixed if
-possible.
-
-To check the entire source tree, you must first download copies of
-``checkpatch.pl``, ``spelling.txt`` and ``const_structs.checkpatch`` available
-in the `Linux master tree`_ *scripts* directory, then set the ``CHECKPATCH``
-environment variable to point to ``checkpatch.pl`` (with the other 2 files in
-the same directory) and build the `checkcodebase` target:
-
-::
-
- make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkcodebase
-
-To just check the style on the files that differ between your local branch and
-the remote master, use:
-
-::
-
- make CHECKPATCH=<path-to-linux>/linux/scripts/checkpatch.pl checkpatch
-
-If you wish to check your patch against something other than the remote master,
-set the ``BASE_COMMIT`` variable to your desired branch. By default, ``BASE_COMMIT``
-is set to ``origin/master``.
-
-Building TF-A
--------------
-
-- Before building TF-A, the environment variable ``CROSS_COMPILE`` must point
- to the Linaro cross compiler.
-
- For AArch64:
-
- ::
-
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
-
- For AArch32:
-
- ::
-
- export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
-
- It is possible to build TF-A using Clang or Arm Compiler 6. To do so
- ``CC`` needs to point to the clang or armclang binary, which will
- also select the clang or armclang assembler. Be aware that the
- GNU linker is used by default. In case of being needed the linker
- can be overridden using the ``LD`` variable. Clang linker version 6 is
- known to work with TF-A.
-
- In both cases ``CROSS_COMPILE`` should be set as described above.
-
- Arm Compiler 6 will be selected when the base name of the path assigned
- to ``CC`` matches the string 'armclang'.
-
- For AArch64 using Arm Compiler 6:
-
- ::
-
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
- make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
-
- Clang will be selected when the base name of the path assigned to ``CC``
- contains the string 'clang'. This is to allow both clang and clang-X.Y
- to work.
-
- For AArch64 using clang:
-
- ::
-
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
- make CC=<path-to-clang>/bin/clang PLAT=<platform> all
-
-- Change to the root directory of the TF-A source tree and build.
-
- For AArch64:
-
- ::
-
- make PLAT=<platform> all
-
- For AArch32:
-
- ::
-
- make PLAT=<platform> ARCH=aarch32 AARCH32_SP=sp_min all
-
- Notes:
-
- - If ``PLAT`` is not specified, ``fvp`` is assumed by default. See the
- `Summary of build options`_ for more information on available build
- options.
-
- - (AArch32 only) Currently only ``PLAT=fvp`` is supported.
-
- - (AArch32 only) ``AARCH32_SP`` is the AArch32 EL3 Runtime Software and it
- corresponds to the BL32 image. A minimal ``AARCH32_SP``, sp_min, is
- provided by TF-A to demonstrate how PSCI Library can be integrated with
- an AArch32 EL3 Runtime Software. Some AArch32 EL3 Runtime Software may
- include other runtime services, for example Trusted OS services. A guide
- to integrate PSCI library with AArch32 EL3 Runtime Software can be found
- `here`_.
-
- - (AArch64 only) The TSP (Test Secure Payload), corresponding to the BL32
- image, is not compiled in by default. Refer to the
- `Building the Test Secure Payload`_ section below.
-
- - By default this produces a release version of the build. To produce a
- debug version instead, refer to the "Debugging options" section below.
-
- - The build process creates products in a ``build`` directory tree, building
- the objects and binaries for each boot loader stage in separate
- sub-directories. The following boot loader binary files are created
- from the corresponding ELF files:
-
- - ``build/<platform>/<build-type>/bl1.bin``
- - ``build/<platform>/<build-type>/bl2.bin``
- - ``build/<platform>/<build-type>/bl31.bin`` (AArch64 only)
- - ``build/<platform>/<build-type>/bl32.bin`` (mandatory for AArch32)
-
- where ``<platform>`` is the name of the chosen platform and ``<build-type>``
- is either ``debug`` or ``release``. The actual number of images might differ
- depending on the platform.
-
-- Build products for a specific build variant can be removed using:
-
- ::
-
- make DEBUG=<D> PLAT=<platform> clean
-
- ... where ``<D>`` is ``0`` or ``1``, as specified when building.
-
- The build tree can be removed completely using:
-
- ::
-
- make realclean
-
-Summary of build options
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The TF-A build system supports the following build options. Unless mentioned
-otherwise, these options are expected to be specified at the build command
-line and are not to be modified in any component makefiles. Note that the
-build system doesn't track dependency for build options. Therefore, if any of
-the build options are changed from a previous build, a clean build must be
-performed.
-
-Common build options
-^^^^^^^^^^^^^^^^^^^^
-
-- ``AARCH32_INSTRUCTION_SET``: Choose the AArch32 instruction set that the
- compiler should use. Valid values are T32 and A32. It defaults to T32 due to
- code having a smaller resulting size.
-
-- ``AARCH32_SP`` : Choose the AArch32 Secure Payload component to be built as
- as the BL32 image when ``ARCH=aarch32``. The value should be the path to the
- directory containing the SP source, relative to the ``bl32/``; the directory
- is expected to contain a makefile called ``<aarch32_sp-value>.mk``.
-
-- ``ARCH`` : Choose the target build architecture for TF-A. It can take either
- ``aarch64`` or ``aarch32`` as values. By default, it is defined to
- ``aarch64``.
-
-- ``ARM_ARCH_MAJOR``: The major version of Arm Architecture to target when
- compiling TF-A. Its value must be numeric, and defaults to 8 . See also,
- *Armv8 Architecture Extensions* and *Armv7 Architecture Extensions* in
- `Firmware Design`_.
-
-- ``ARM_ARCH_MINOR``: The minor version of Arm Architecture to target when
- compiling TF-A. Its value must be a numeric, and defaults to 0. See also,
- *Armv8 Architecture Extensions* in `Firmware Design`_.
-
-- ``BL2``: This is an optional build option which specifies the path to BL2
- image for the ``fip`` target. In this case, the BL2 in the TF-A will not be
- built.
-
-- ``BL2U``: This is an optional build option which specifies the path to
- BL2U image. In this case, the BL2U in TF-A will not be built.
-
-- ``BL2_AT_EL3``: This is an optional build option that enables the use of
- BL2 at EL3 execution level.
-
-- ``BL2_IN_XIP_MEM``: In some use-cases BL2 will be stored in eXecute In Place
- (XIP) memory, like BL1. In these use-cases, it is necessary to initialize
- the RW sections in RAM, while leaving the RO sections in place. This option
- enable this use-case. For now, this option is only supported when BL2_AT_EL3
- is set to '1'.
-
-- ``BL31``: This is an optional build option which specifies the path to
- BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not
- be built.
-
-- ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
- file that contains the BL31 private key in PEM format. If ``SAVE_KEYS=1``,
- this file name will be used to save the key.
-
-- ``BL32``: This is an optional build option which specifies the path to
- BL32 image for the ``fip`` target. In this case, the BL32 in TF-A will not
- be built.
-
-- ``BL32_EXTRA1``: This is an optional build option which specifies the path to
- Trusted OS Extra1 image for the ``fip`` target.
-
-- ``BL32_EXTRA2``: This is an optional build option which specifies the path to
- Trusted OS Extra2 image for the ``fip`` target.
-
-- ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
- file that contains the BL32 private key in PEM format. If ``SAVE_KEYS=1``,
- this file name will be used to save the key.
-
-- ``BL33``: Path to BL33 image in the host file system. This is mandatory for
- ``fip`` target in case TF-A BL2 is used.
-
-- ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
- file that contains the BL33 private key in PEM format. If ``SAVE_KEYS=1``,
- this file name will be used to save the key.
-
-- ``BUILD_MESSAGE_TIMESTAMP``: String used to identify the time and date of the
- compilation of each build. It must be set to a C string (including quotes
- where applicable). Defaults to a string that contains the time and date of
- the compilation.
-
-- ``BUILD_STRING``: Input string for VERSION_STRING, which allows the TF-A
- build to be uniquely identified. Defaults to the current git commit id.
-
-- ``CFLAGS``: Extra user options appended on the compiler's command line in
- addition to the options set by the build system.
-
-- ``COLD_BOOT_SINGLE_CPU``: This option indicates whether the platform may
- release several CPUs out of reset. It can take either 0 (several CPUs may be
- brought up) or 1 (only one CPU will ever be brought up during cold reset).
- Default is 0. If the platform always brings up a single CPU, there is no
- need to distinguish between primary and secondary CPUs and the boot path can
- be optimised. The ``plat_is_my_cpu_primary()`` and
- ``plat_secondary_cold_boot_setup()`` platform porting interfaces do not need
- to be implemented in this case.
-
-- ``CRASH_REPORTING``: A non-zero value enables a console dump of processor
- register state when an unexpected exception occurs during execution of
- BL31. This option defaults to the value of ``DEBUG`` - i.e. by default
- this is only enabled for a debug build of the firmware.
-
-- ``CREATE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
- certificate generation tool to create new keys in case no valid keys are
- present or specified. Allowed options are '0' or '1'. Default is '1'.
-
-- ``CTX_INCLUDE_AARCH32_REGS`` : Boolean option that, when set to 1, will cause
- the AArch32 system registers to be included when saving and restoring the
- CPU context. The option must be set to 0 for AArch64-only platforms (that
- is on hardware that does not implement AArch32, or at least not at EL1 and
- higher ELs). Default value is 1.
-
-- ``CTX_INCLUDE_FPREGS``: Boolean option that, when set to 1, will cause the FP
- registers to be included when saving and restoring the CPU context. Default
- is 0.
-
-- ``CTX_INCLUDE_PAUTH_REGS``: Boolean option that, when set to 1, allows
- Pointer Authentication for **Secure world**. This will cause the
- Armv8.3-PAuth registers to be included when saving and restoring the CPU
- context as part of a world switch. Default value is 0. Pointer Authentication
- is an experimental feature.
-
- Note that, if the CPU supports it, Pointer Authentication is allowed for
- Non-secure world irrespectively of the value of this flag. "Allowed" means
- that accesses to PAuth-related registers or execution of PAuth-related
- instructions will not be trapped to EL3. As such, usage or not of PAuth in
- Non-secure world images, depends on those images themselves.
-
-- ``DEBUG``: Chooses between a debug and release build. It can take either 0
- (release) or 1 (debug) as values. 0 is the default.
-
-- ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation
- of the binary image. If set to 1, then only the ELF image is built.
- 0 is the default.
-
-- ``DYN_DISABLE_AUTH``: Provides the capability to dynamically disable Trusted
- Board Boot authentication at runtime. This option is meant to be enabled only
- for development platforms. ``TRUSTED_BOARD_BOOT`` flag must be set if this
- flag has to be enabled. 0 is the default.
-
-- ``EL3_PAYLOAD_BASE``: This option enables booting an EL3 payload instead of
- the normal boot flow. It must specify the entry point address of the EL3
- payload. Please refer to the "Booting an EL3 payload" section for more
- details.
-
-- ``ENABLE_AMU``: Boolean option to enable Activity Monitor Unit extensions.
- This is an optional architectural feature available on v8.4 onwards. Some
- v8.2 implementations also implement an AMU and this option can be used to
- enable this feature on those systems as well. Default is 0.
-
-- ``ENABLE_ASSERTIONS``: This option controls whether or not calls to ``assert()``
- are compiled out. For debug builds, this option defaults to 1, and calls to
- ``assert()`` are left in place. For release builds, this option defaults to 0
- and calls to ``assert()`` function are compiled out. This option can be set
- independently of ``DEBUG``. It can also be used to hide any auxiliary code
- that is only required for the assertion and does not fit in the assertion
- itself.
-
-- ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace
- dumps or not. It is supported in both AArch64 and AArch32. However, in
- AArch32 the format of the frame records are not defined in the AAPCS and they
- are defined by the implementation. This implementation of backtrace only
- supports the format used by GCC when T32 interworking is disabled. For this
- reason enabling this option in AArch32 will force the compiler to only
- generate A32 code. This option is enabled by default only in AArch64 debug
- builds, but this behaviour can be overridden in each platform's Makefile or
- in the build command line.
-
-- ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
- feature. MPAM is an optional Armv8.4 extension that enables various memory
- system components and resources to define partitions; software running at
- various ELs can assign themselves to desired partition to control their
- performance aspects.
-
- When this option is set to ``1``, EL3 allows lower ELs to access their own
- MPAM registers without trapping into EL3. This option doesn't make use of
- partitioning in EL3, however. Platform initialisation code should configure
- and use partitions in EL3 as required. This option defaults to ``0``.
-
-- ``ENABLE_PAUTH``: Boolean option to enable Armv8.3 Pointer Authentication
- for **TF-A BL images themselves**. If enabled, the compiler must support the
- ``-msign-return-address`` option. This flag defaults to 0. Pointer
- Authentication is an experimental feature.
-
- If this flag is enabled, ``CTX_INCLUDE_PAUTH_REGS`` must also be enabled.
-
-- ``ENABLE_PIE``: Boolean option to enable Position Independent Executable(PIE)
- support within generic code in TF-A. This option is currently only supported
- in BL31. Default is 0.
-
-- ``ENABLE_PMF``: Boolean option to enable support for optional Performance
- Measurement Framework(PMF). Default is 0.
-
-- ``ENABLE_PSCI_STAT``: Boolean option to enable support for optional PSCI
- functions ``PSCI_STAT_RESIDENCY`` and ``PSCI_STAT_COUNT``. Default is 0.
- In the absence of an alternate stat collection backend, ``ENABLE_PMF`` must
- be enabled. If ``ENABLE_PMF`` is set, the residency statistics are tracked in
- software.
-
-- ``ENABLE_RUNTIME_INSTRUMENTATION``: Boolean option to enable runtime
- instrumentation which injects timestamp collection points into TF-A to
- allow runtime performance to be measured. Currently, only PSCI is
- instrumented. Enabling this option enables the ``ENABLE_PMF`` build option
- as well. Default is 0.
-
-- ``ENABLE_SPE_FOR_LOWER_ELS`` : Boolean option to enable Statistical Profiling
- extensions. This is an optional architectural feature for AArch64.
- The default is 1 but is automatically disabled when the target architecture
- is AArch32.
-
-- ``ENABLE_SPM`` : Boolean option to enable the Secure Partition Manager (SPM).
- Refer to the `Secure Partition Manager Design guide`_ for more details about
- this feature. Default is 0.
-
-- ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension
- (SVE) for the Non-secure world only. SVE is an optional architectural feature
- for AArch64. Note that when SVE is enabled for the Non-secure world, access
- to SIMD and floating-point functionality from the Secure world is disabled.
- This is to avoid corruption of the Non-secure world data in the Z-registers
- which are aliased by the SIMD and FP registers. The build option is not
- compatible with the ``CTX_INCLUDE_FPREGS`` build option, and will raise an
- assert on platforms where SVE is implemented and ``ENABLE_SVE_FOR_NS`` set to
- 1. The default is 1 but is automatically disabled when the target
- architecture is AArch32.
-
-- ``ENABLE_STACK_PROTECTOR``: String option to enable the stack protection
- checks in GCC. Allowed values are "all", "strong", "default" and "none". The
- default value is set to "none". "strong" is the recommended stack protection
- level if this feature is desired. "none" disables the stack protection. For
- all values other than "none", the ``plat_get_stack_protector_canary()``
- platform hook needs to be implemented. The value is passed as the last
- component of the option ``-fstack-protector-$ENABLE_STACK_PROTECTOR``.
-
-- ``ERROR_DEPRECATED``: This option decides whether to treat the usage of
- deprecated platform APIs, helper functions or drivers within Trusted
- Firmware as error. It can take the value 1 (flag the use of deprecated
- APIs as error) or 0. The default is 0.
-
-- ``EL3_EXCEPTION_HANDLING``: When set to ``1``, enable handling of exceptions
- targeted at EL3. When set ``0`` (default), no exceptions are expected or
- handled at EL3, and a panic will result. This is supported only for AArch64
- builds.
-
-- ``FAULT_INJECTION_SUPPORT``: ARMv8.4 extensions introduced support for fault
- injection from lower ELs, and this build option enables lower ELs to use
- Error Records accessed via System Registers to inject faults. This is
- applicable only to AArch64 builds.
-
- This feature is intended for testing purposes only, and is advisable to keep
- disabled for production images.
-
-- ``FIP_NAME``: This is an optional build option which specifies the FIP
- filename for the ``fip`` target. Default is ``fip.bin``.
-
-- ``FWU_FIP_NAME``: This is an optional build option which specifies the FWU
- FIP filename for the ``fwu_fip`` target. Default is ``fwu_fip.bin``.
-
-- ``GENERATE_COT``: Boolean flag used to build and execute the ``cert_create``
- tool to create certificates as per the Chain of Trust described in
- `Trusted Board Boot`_. The build system then calls ``fiptool`` to
- include the certificates in the FIP and FWU_FIP. Default value is '0'.
-
- Specify both ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=1`` to include support
- for the Trusted Board Boot feature in the BL1 and BL2 images, to generate
- the corresponding certificates, and to include those certificates in the
- FIP and FWU_FIP.
-
- Note that if ``TRUSTED_BOARD_BOOT=0`` and ``GENERATE_COT=1``, the BL1 and BL2
- images will not include support for Trusted Board Boot. The FIP will still
- include the corresponding certificates. This FIP can be used to verify the
- Chain of Trust on the host machine through other mechanisms.
-
- Note that if ``TRUSTED_BOARD_BOOT=1`` and ``GENERATE_COT=0``, the BL1 and BL2
- images will include support for Trusted Board Boot, but the FIP and FWU_FIP
- will not include the corresponding certificates, causing a boot failure.
-
-- ``GICV2_G0_FOR_EL3``: Unlike GICv3, the GICv2 architecture doesn't have
- inherent support for specific EL3 type interrupts. Setting this build option
- to ``1`` assumes GICv2 *Group 0* interrupts are expected to target EL3, both
- by `platform abstraction layer`__ and `Interrupt Management Framework`__.
- This allows GICv2 platforms to enable features requiring EL3 interrupt type.
- This also means that all GICv2 Group 0 interrupts are delivered to EL3, and
- the Secure Payload interrupts needs to be synchronously handed over to Secure
- EL1 for handling. The default value of this option is ``0``, which means the
- Group 0 interrupts are assumed to be handled by Secure EL1.
-
- .. __: `platform-interrupt-controller-API.rst`
- .. __: `interrupt-framework-design.rst`
-
-- ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError
- Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to
- ``0`` (default), these exceptions will be trapped in the current exception
- level (or in EL1 if the current exception level is EL0).
-
-- ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific
- software operations are required for CPUs to enter and exit coherency.
- However, newer systems exist where CPUs' entry to and exit from coherency
- is managed in hardware. Such systems require software to only initiate these
- operations, and the rest is managed in hardware, minimizing active software
- management. In such systems, this boolean option enables TF-A to carry out
- build and run-time optimizations during boot and power management operations.
- This option defaults to 0 and if it is enabled, then it implies
- ``WARMBOOT_ENABLE_DCACHE_EARLY`` is also enabled.
-
- If this flag is disabled while the platform which TF-A is compiled for
- includes cores that manage coherency in hardware, then a compilation error is
- generated. This is based on the fact that a system cannot have, at the same
- time, cores that manage coherency in hardware and cores that don't. In other
- words, a platform cannot have, at the same time, cores that require
- ``HW_ASSISTED_COHERENCY=1`` and cores that require
- ``HW_ASSISTED_COHERENCY=0``.
-
- Note that, when ``HW_ASSISTED_COHERENCY`` is enabled, version 2 of
- translation library (xlat tables v2) must be used; version 1 of translation
- library is not supported.
-
-- ``JUNO_AARCH32_EL3_RUNTIME``: This build flag enables you to execute EL3
- runtime software in AArch32 mode, which is required to run AArch32 on Juno.
- By default this flag is set to '0'. Enabling this flag builds BL1 and BL2 in
- AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable
- images.
-
-- ``KEY_ALG``: This build flag enables the user to select the algorithm to be
- used for generating the PKCS keys and subsequent signing of the certificate.
- It accepts 3 values: ``rsa``, ``rsa_1_5`` and ``ecdsa``. The option
- ``rsa_1_5`` is the legacy PKCS#1 RSA 1.5 algorithm which is not TBBR
- compliant and is retained only for compatibility. The default value of this
- flag is ``rsa`` which is the TBBR compliant PKCS#1 RSA 2.1 scheme.
-
-- ``HASH_ALG``: This build flag enables the user to select the secure hash
- algorithm. It accepts 3 values: ``sha256``, ``sha384`` and ``sha512``.
- The default value of this flag is ``sha256``.
-
-- ``LDFLAGS``: Extra user options appended to the linkers' command line in
- addition to the one set by the build system.
-
-- ``LOG_LEVEL``: Chooses the log level, which controls the amount of console log
- output compiled into the build. This should be one of the following:
-
- ::
-
- 0 (LOG_LEVEL_NONE)
- 10 (LOG_LEVEL_ERROR)
- 20 (LOG_LEVEL_NOTICE)
- 30 (LOG_LEVEL_WARNING)
- 40 (LOG_LEVEL_INFO)
- 50 (LOG_LEVEL_VERBOSE)
-
- All log output up to and including the selected log level is compiled into
- the build. The default value is 40 in debug builds and 20 in release builds.
-
-- ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
- specifies the file that contains the Non-Trusted World private key in PEM
- format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
-
-- ``NS_BL2U``: Path to NS_BL2U image in the host file system. This image is
- optional. It is only needed if the platform makefile specifies that it
- is required in order to build the ``fwu_fip`` target.
-
-- ``NS_TIMER_SWITCH``: Enable save and restore for non-secure timer register
- contents upon world switch. It can take either 0 (don't save and restore) or
- 1 (do save and restore). 0 is the default. An SPD may set this to 1 if it
- wants the timer registers to be saved and restored.
-
-- ``OVERRIDE_LIBC``: This option allows platforms to override the default libc
- for the BL image. It can be either 0 (include) or 1 (remove). The default
- value is 0.
-
-- ``PL011_GENERIC_UART``: Boolean option to indicate the PL011 driver that
- the underlying hardware is not a full PL011 UART but a minimally compliant
- generic UART, which is a subset of the PL011. The driver will not access
- any register that is not part of the SBSA generic UART specification.
- Default value is 0 (a full PL011 compliant UART is present).
-
-- ``PLAT``: Choose a platform to build TF-A for. The chosen platform name
- must be subdirectory of any depth under ``plat/``, and must contain a
- platform makefile named ``platform.mk``. For example, to build TF-A for the
- Arm Juno board, select PLAT=juno.
-
-- ``PRELOADED_BL33_BASE``: This option enables booting a preloaded BL33 image
- instead of the normal boot flow. When defined, it must specify the entry
- point address for the preloaded BL33 image. This option is incompatible with
- ``EL3_PAYLOAD_BASE``. If both are defined, ``EL3_PAYLOAD_BASE`` has priority
- over ``PRELOADED_BL33_BASE``.
-
-- ``PROGRAMMABLE_RESET_ADDRESS``: This option indicates whether the reset
- vector address can be programmed or is fixed on the platform. It can take
- either 0 (fixed) or 1 (programmable). Default is 0. If the platform has a
- programmable reset address, it is expected that a CPU will start executing
- code directly at the right address, both on a cold and warm reset. In this
- case, there is no need to identify the entrypoint on boot and the boot path
- can be optimised. The ``plat_get_my_entrypoint()`` platform porting interface
- does not need to be implemented in this case.
-
-- ``PSCI_EXTENDED_STATE_ID``: As per PSCI1.0 Specification, there are 2 formats
- possible for the PSCI power-state parameter: original and extended State-ID
- formats. This flag if set to 1, configures the generic PSCI layer to use the
- extended format. The default value of this flag is 0, which means by default
- the original power-state format is used by the PSCI implementation. This flag
- should be specified by the platform makefile and it governs the return value
- of PSCI_FEATURES API for CPU_SUSPEND smc function id. When this option is
- enabled on Arm platforms, the option ``ARM_RECOM_STATE_ID_ENC`` needs to be
- set to 1 as well.
-
-- ``RAS_EXTENSION``: When set to ``1``, enable Armv8.2 RAS features. RAS features
- are an optional extension for pre-Armv8.2 CPUs, but are mandatory for Armv8.2
- or later CPUs.
-
- When ``RAS_EXTENSION`` is set to ``1``, ``HANDLE_EA_EL3_FIRST`` must also be
- set to ``1``.
-
- This option is disabled by default.
-
-- ``RESET_TO_BL31``: Enable BL31 entrypoint as the CPU reset vector instead
- of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
- entrypoint) or 1 (CPU reset to BL31 entrypoint).
- The default value is 0.
-
-- ``RESET_TO_SP_MIN``: SP_MIN is the minimal AArch32 Secure Payload provided
- in TF-A. This flag configures SP_MIN entrypoint as the CPU reset vector
- instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1
- entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0.
-
-- ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
- file that contains the ROT private key in PEM format. If ``SAVE_KEYS=1``, this
- file name will be used to save the key.
-
-- ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the
- certificate generation tool to save the keys used to establish the Chain of
- Trust. Allowed options are '0' or '1'. Default is '0' (do not save).
-
-- ``SCP_BL2``: Path to SCP_BL2 image in the host file system. This image is optional.
- If a SCP_BL2 image is present then this option must be passed for the ``fip``
- target.
-
-- ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the
- file that contains the SCP_BL2 private key in PEM format. If ``SAVE_KEYS=1``,
- this file name will be used to save the key.
-
-- ``SCP_BL2U``: Path to SCP_BL2U image in the host file system. This image is
- optional. It is only needed if the platform makefile specifies that it
- is required in order to build the ``fwu_fip`` target.
-
-- ``SDEI_SUPPORT``: Setting this to ``1`` enables support for Software
- Delegated Exception Interface to BL31 image. This defaults to ``0``.
-
- When set to ``1``, the build option ``EL3_EXCEPTION_HANDLING`` must also be
- set to ``1``.
-
-- ``SEPARATE_CODE_AND_RODATA``: Whether code and read-only data should be
- isolated on separate memory pages. This is a trade-off between security and
- memory usage. See "Isolating code and read-only data on separate memory
- pages" section in `Firmware Design`_. This flag is disabled by default and
- affects all BL images.
-
-- ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A.
- This build option is only valid if ``ARCH=aarch64``. The value should be
- the path to the directory containing the SPD source, relative to
- ``services/spd/``; the directory is expected to contain a makefile called
- ``<spd-value>.mk``.
-
-- ``SPIN_ON_BL1_EXIT``: This option introduces an infinite loop in BL1. It can
- take either 0 (no loop) or 1 (add a loop). 0 is the default. This loop stops
- execution in BL1 just before handing over to BL31. At this point, all
- firmware images have been loaded in memory, and the MMU and caches are
- turned off. Refer to the "Debugging options" section for more details.
-
-- ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
- secure interrupts (caught through the FIQ line). Platforms can enable
- this directive if they need to handle such interruption. When enabled,
- the FIQ are handled in monitor mode and non secure world is not allowed
- to mask these events. Platforms that enable FIQ handling in SP_MIN shall
- implement the api ``sp_min_plat_fiq_handler()``. The default value is 0.
-
-- ``TRUSTED_BOARD_BOOT``: Boolean flag to include support for the Trusted Board
- Boot feature. When set to '1', BL1 and BL2 images include support to load
- and verify the certificates and images in a FIP, and BL1 includes support
- for the Firmware Update. The default value is '0'. Generation and inclusion
- of certificates in the FIP and FWU_FIP depends upon the value of the
- ``GENERATE_COT`` option.
-
- Note: This option depends on ``CREATE_KEYS`` to be enabled. If the keys
- already exist in disk, they will be overwritten without further notice.
-
-- ``TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It
- specifies the file that contains the Trusted World private key in PEM
- format. If ``SAVE_KEYS=1``, this file name will be used to save the key.
-
-- ``TSP_INIT_ASYNC``: Choose BL32 initialization method as asynchronous or
- synchronous, (see "Initializing a BL32 Image" section in
- `Firmware Design`_). It can take the value 0 (BL32 is initialized using
- synchronous method) or 1 (BL32 is initialized using asynchronous method).
- Default is 0.
-
-- ``TSP_NS_INTR_ASYNC_PREEMPT``: A non zero value enables the interrupt
- routing model which routes non-secure interrupts asynchronously from TSP
- to EL3 causing immediate preemption of TSP. The EL3 is responsible
- for saving and restoring the TSP context in this routing model. The
- default routing model (when the value is 0) is to route non-secure
- interrupts to TSP allowing it to save its context and hand over
- synchronously to EL3 via an SMC.
-
- Note: when ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT``
- must also be set to ``1``.
-
-- ``USE_ARM_LINK``: This flag determines whether to enable support for ARM
- linker. When the ``LINKER`` build variable points to the armlink linker,
- this flag is enabled automatically. To enable support for armlink, platforms
- will have to provide a scatter file for the BL image. Currently, Tegra
- platforms use the armlink support to compile BL3-1 images.
-
-- ``USE_COHERENT_MEM``: This flag determines whether to include the coherent
- memory region in the BL memory map or not (see "Use of Coherent memory in
- TF-A" section in `Firmware Design`_). It can take the value 1
- (Coherent memory region is included) or 0 (Coherent memory region is
- excluded). Default is 1.
-
-- ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
- This feature creates a library of functions to be placed in ROM and thus
- reduces SRAM usage. Refer to `Library at ROM`_ for further details. Default
- is 0.
-
-- ``V``: Verbose build. If assigned anything other than 0, the build commands
- are printed. Default is 0.
-
-- ``VERSION_STRING``: String used in the log output for each TF-A image.
- Defaults to a string formed by concatenating the version number, build type
- and build string.
-
-- ``WARMBOOT_ENABLE_DCACHE_EARLY`` : Boolean option to enable D-cache early on
- the CPU after warm boot. This is applicable for platforms which do not
- require interconnect programming to enable cache coherency (eg: single
- cluster platforms). If this option is enabled, then warm boot path
- enables D-caches immediately after enabling MMU. This option defaults to 0.
-
-Arm development platform specific build options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- ``ARM_BL31_IN_DRAM``: Boolean option to select loading of BL31 in TZC secured
- DRAM. By default, BL31 is in the secure SRAM. Set this flag to 1 to load
- BL31 in TZC secured DRAM. If TSP is present, then setting this option also
- sets the TSP location to DRAM and ignores the ``ARM_TSP_RAM_LOCATION`` build
- flag.
-
-- ``ARM_CONFIG_CNTACR``: boolean option to unlock access to the ``CNTBase<N>``
- frame registers by setting the ``CNTCTLBase.CNTACR<N>`` register bits. The
- frame number ``<N>`` is defined by ``PLAT_ARM_NSTIMER_FRAME_ID``, which should
- match the frame used by the Non-Secure image (normally the Linux kernel).
- Default is true (access to the frame is allowed).
-
-- ``ARM_DISABLE_TRUSTED_WDOG``: boolean option to disable the Trusted Watchdog.
- By default, Arm platforms use a watchdog to trigger a system reset in case
- an error is encountered during the boot process (for example, when an image
- could not be loaded or authenticated). The watchdog is enabled in the early
- platform setup hook at BL1 and disabled in the BL1 prepare exit hook. The
- Trusted Watchdog may be disabled at build time for testing or development
- purposes.
-
-- ``ARM_LINUX_KERNEL_AS_BL33``: The Linux kernel expects registers x0-x3 to
- have specific values at boot. This boolean option allows the Trusted Firmware
- to have a Linux kernel image as BL33 by preparing the registers to these
- values before jumping to BL33. This option defaults to 0 (disabled). For
- AArch64 ``RESET_TO_BL31`` and for AArch32 ``RESET_TO_SP_MIN`` must be 1 when
- using it. If this option is set to 1, ``ARM_PRELOADED_DTB_BASE`` must be set
- to the location of a device tree blob (DTB) already loaded in memory. The
- Linux Image address must be specified using the ``PRELOADED_BL33_BASE``
- option.
-
-- ``ARM_PLAT_MT``: This flag determines whether the Arm platform layer has to
- cater for the multi-threading ``MT`` bit when accessing MPIDR. When this flag
- is set, the functions which deal with MPIDR assume that the ``MT`` bit in
- MPIDR is set and access the bit-fields in MPIDR accordingly. Default value of
- this flag is 0. Note that this option is not used on FVP platforms.
-
-- ``ARM_RECOM_STATE_ID_ENC``: The PSCI1.0 specification recommends an encoding
- for the construction of composite state-ID in the power-state parameter.
- The existing PSCI clients currently do not support this encoding of
- State-ID yet. Hence this flag is used to configure whether to use the
- recommended State-ID encoding or not. The default value of this flag is 0,
- in which case the platform is configured to expect NULL in the State-ID
- field of power-state parameter.
-
-- ``ARM_ROTPK_LOCATION``: used when ``TRUSTED_BOARD_BOOT=1``. It specifies the
- location of the ROTPK hash returned by the function ``plat_get_rotpk_info()``
- for Arm platforms. Depending on the selected option, the proper private key
- must be specified using the ``ROT_KEY`` option when building the Trusted
- Firmware. This private key will be used by the certificate generation tool
- to sign the BL2 and Trusted Key certificates. Available options for
- ``ARM_ROTPK_LOCATION`` are:
-
- - ``regs`` : return the ROTPK hash stored in the Trusted root-key storage
- registers. The private key corresponding to this ROTPK hash is not
- currently available.
- - ``devel_rsa`` : return a development public key hash embedded in the BL1
- and BL2 binaries. This hash has been obtained from the RSA public key
- ``arm_rotpk_rsa.der``, located in ``plat/arm/board/common/rotpk``. To use
- this option, ``arm_rotprivk_rsa.pem`` must be specified as ``ROT_KEY`` when
- creating the certificates.
- - ``devel_ecdsa`` : return a development public key hash embedded in the BL1
- and BL2 binaries. This hash has been obtained from the ECDSA public key
- ``arm_rotpk_ecdsa.der``, located in ``plat/arm/board/common/rotpk``. To use
- this option, ``arm_rotprivk_ecdsa.pem`` must be specified as ``ROT_KEY``
- when creating the certificates.
-
-- ``ARM_TSP_RAM_LOCATION``: location of the TSP binary. Options:
-
- - ``tsram`` : Trusted SRAM (default option when TBB is not enabled)
- - ``tdram`` : Trusted DRAM (if available)
- - ``dram`` : Secure region in DRAM (default option when TBB is enabled,
- configured by the TrustZone controller)
-
-- ``ARM_XLAT_TABLES_LIB_V1``: boolean option to compile TF-A with version 1
- of the translation tables library instead of version 2. It is set to 0 by
- default, which selects version 2.
-
-- ``ARM_CRYPTOCELL_INTEG`` : bool option to enable TF-A to invoke Arm®
- TrustZone® CryptoCell functionality for Trusted Board Boot on capable Arm
- platforms. If this option is specified, then the path to the CryptoCell
- SBROM library must be specified via ``CCSBROM_LIB_PATH`` flag.
-
-For a better understanding of these options, the Arm development platform memory
-map is explained in the `Firmware Design`_.
-
-Arm CSS platform specific build options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- ``CSS_DETECT_PRE_1_7_0_SCP``: Boolean flag to detect SCP version
- incompatibility. Version 1.7.0 of the SCP firmware made a non-backwards
- compatible change to the MTL protocol, used for AP/SCP communication.
- TF-A no longer supports earlier SCP versions. If this option is set to 1
- then TF-A will detect if an earlier version is in use. Default is 1.
-
-- ``CSS_LOAD_SCP_IMAGES``: Boolean flag, which when set, adds SCP_BL2 and
- SCP_BL2U to the FIP and FWU_FIP respectively, and enables them to be loaded
- during boot. Default is 1.
-
-- ``CSS_USE_SCMI_SDS_DRIVER``: Boolean flag which selects SCMI/SDS drivers
- instead of SCPI/BOM driver for communicating with the SCP during power
- management operations and for SCP RAM Firmware transfer. If this option
- is set to 1, then SCMI/SDS drivers will be used. Default is 0.
-
-Arm FVP platform specific build options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- ``FVP_CLUSTER_COUNT`` : Configures the cluster count to be used to
- build the topology tree within TF-A. By default TF-A is configured for dual
- cluster topology and this option can be used to override the default value.
-
-- ``FVP_INTERCONNECT_DRIVER``: Selects the interconnect driver to be built. The
- default interconnect driver depends on the value of ``FVP_CLUSTER_COUNT`` as
- explained in the options below:
-
- - ``FVP_CCI`` : The CCI driver is selected. This is the default
- if 0 < ``FVP_CLUSTER_COUNT`` <= 2.
- - ``FVP_CCN`` : The CCN driver is selected. This is the default
- if ``FVP_CLUSTER_COUNT`` > 2.
-
-- ``FVP_MAX_CPUS_PER_CLUSTER``: Sets the maximum number of CPUs implemented in
- a single cluster. This option defaults to 4.
-
-- ``FVP_MAX_PE_PER_CPU``: Sets the maximum number of PEs implemented on any CPU
- in the system. This option defaults to 1. Note that the build option
- ``ARM_PLAT_MT`` doesn't have any effect on FVP platforms.
-
-- ``FVP_USE_GIC_DRIVER`` : Selects the GIC driver to be built. Options:
-
- - ``FVP_GIC600`` : The GIC600 implementation of GICv3 is selected
- - ``FVP_GICV2`` : The GICv2 only driver is selected
- - ``FVP_GICV3`` : The GICv3 only driver is selected (default option)
-
-- ``FVP_USE_SP804_TIMER`` : Use the SP804 timer instead of the Generic Timer
- for functions that wait for an arbitrary time length (udelay and mdelay).
- The default value is 0.
-
-- ``FVP_HW_CONFIG_DTS`` : Specify the path to the DTS file to be compiled
- to DTB and packaged in FIP as the HW_CONFIG. See `Firmware Design`_ for
- details on HW_CONFIG. By default, this is initialized to a sensible DTS
- file in ``fdts/`` folder depending on other build options. But some cases,
- like shifted affinity format for MPIDR, cannot be detected at build time
- and this option is needed to specify the appropriate DTS file.
-
-- ``FVP_HW_CONFIG`` : Specify the path to the HW_CONFIG blob to be packaged in
- FIP. See `Firmware Design`_ for details on HW_CONFIG. This option is
- similar to the ``FVP_HW_CONFIG_DTS`` option, but it directly specifies the
- HW_CONFIG blob instead of the DTS file. This option is useful to override
- the default HW_CONFIG selected by the build system.
-
-ARM JUNO platform specific build options
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- ``JUNO_TZMP1`` : Boolean option to configure Juno to be used for TrustZone
- Media Protection (TZ-MP1). Default value of this flag is 0.
-
-Debugging options
-~~~~~~~~~~~~~~~~~
-
-To compile a debug version and make the build more verbose use
-
-::
-
- make PLAT=<platform> DEBUG=1 V=1 all
-
-AArch64 GCC uses DWARF version 4 debugging symbols by default. Some tools (for
-example DS-5) might not support this and may need an older version of DWARF
-symbols to be emitted by GCC. This can be achieved by using the
-``-gdwarf-<version>`` flag, with the version being set to 2 or 3. Setting the
-version to 2 is recommended for DS-5 versions older than 5.16.
-
-When debugging logic problems it might also be useful to disable all compiler
-optimizations by using ``-O0``.
-
-NOTE: Using ``-O0`` could cause output images to be larger and base addresses
-might need to be recalculated (see the **Memory layout on Arm development
-platforms** section in the `Firmware Design`_).
-
-Extra debug options can be passed to the build system by setting ``CFLAGS`` or
-``LDFLAGS``:
-
-.. code:: makefile
-
- CFLAGS='-O0 -gdwarf-2' \
- make PLAT=<platform> DEBUG=1 V=1 all
-
-Note that using ``-Wl,`` style compilation driver options in ``CFLAGS`` will be
-ignored as the linker is called directly.
-
-It is also possible to introduce an infinite loop to help in debugging the
-post-BL2 phase of TF-A. This can be done by rebuilding BL1 with the
-``SPIN_ON_BL1_EXIT=1`` build flag. Refer to the `Summary of build options`_
-section. In this case, the developer may take control of the target using a
-debugger when indicated by the console output. When using DS-5, the following
-commands can be used:
-
-::
-
- # Stop target execution
- interrupt
-
- #
- # Prepare your debugging environment, e.g. set breakpoints
- #
-
- # Jump over the debug loop
- set var $AARCH64::$Core::$PC = $AARCH64::$Core::$PC + 4
-
- # Resume execution
- continue
-
-Building the Test Secure Payload
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The TSP is coupled with a companion runtime service in the BL31 firmware,
-called the TSPD. Therefore, if you intend to use the TSP, the BL31 image
-must be recompiled as well. For more information on SPs and SPDs, see the
-`Secure-EL1 Payloads and Dispatchers`_ section in the `Firmware Design`_.
-
-First clean the TF-A build directory to get rid of any previous BL31 binary.
-Then to build the TSP image use:
-
-::
-
- make PLAT=<platform> SPD=tspd all
-
-An additional boot loader binary file is created in the ``build`` directory:
-
-::
-
- build/<platform>/<build-type>/bl32.bin
-
-
-Building and using the FIP tool
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Firmware Image Package (FIP) is a packaging format used by TF-A to package
-firmware images in a single binary. The number and type of images that should
-be packed in a FIP is platform specific and may include TF-A images and other
-firmware images required by the platform. For example, most platforms require
-a BL33 image which corresponds to the normal world bootloader (e.g. UEFI or
-U-Boot).
-
-The TF-A build system provides the make target ``fip`` to create a FIP file
-for the specified platform using the FIP creation tool included in the TF-A
-project. Examples below show how to build a FIP file for FVP, packaging TF-A
-and BL33 images.
-
-For AArch64:
-
-::
-
- make PLAT=fvp BL33=<path-to>/bl33.bin fip
-
-For AArch32:
-
-::
-
- make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=<path-to>/bl33.bin fip
-
-The resulting FIP may be found in:
-
-::
-
- build/fvp/<build-type>/fip.bin
-
-For advanced operations on FIP files, it is also possible to independently build
-the tool and create or modify FIPs using this tool. To do this, follow these
-steps:
-
-It is recommended to remove old artifacts before building the tool:
-
-::
-
- make -C tools/fiptool clean
-
-Build the tool:
-
-::
-
- make [DEBUG=1] [V=1] fiptool
-
-The tool binary can be located in:
-
-::
-
- ./tools/fiptool/fiptool
-
-Invoking the tool with ``help`` will print a help message with all available
-options.
-
-Example 1: create a new Firmware package ``fip.bin`` that contains BL2 and BL31:
-
-::
-
- ./tools/fiptool/fiptool create \
- --tb-fw build/<platform>/<build-type>/bl2.bin \
- --soc-fw build/<platform>/<build-type>/bl31.bin \
- fip.bin
-
-Example 2: view the contents of an existing Firmware package:
-
-::
-
- ./tools/fiptool/fiptool info <path-to>/fip.bin
-
-Example 3: update the entries of an existing Firmware package:
-
-::
-
- # Change the BL2 from Debug to Release version
- ./tools/fiptool/fiptool update \
- --tb-fw build/<platform>/release/bl2.bin \
- build/<platform>/debug/fip.bin
-
-Example 4: unpack all entries from an existing Firmware package:
-
-::
-
- # Images will be unpacked to the working directory
- ./tools/fiptool/fiptool unpack <path-to>/fip.bin
-
-Example 5: remove an entry from an existing Firmware package:
-
-::
-
- ./tools/fiptool/fiptool remove \
- --tb-fw build/<platform>/debug/fip.bin
-
-Note that if the destination FIP file exists, the create, update and
-remove operations will automatically overwrite it.
-
-The unpack operation will fail if the images already exist at the
-destination. In that case, use -f or --force to continue.
-
-More information about FIP can be found in the `Firmware Design`_ document.
-
-Building FIP images with support for Trusted Board Boot
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Trusted Board Boot primarily consists of the following two features:
-
-- Image Authentication, described in `Trusted Board Boot`_, and
-- Firmware Update, described in `Firmware Update`_
-
-The following steps should be followed to build FIP and (optionally) FWU_FIP
-images with support for these features:
-
-#. Fulfill the dependencies of the ``mbedtls`` cryptographic and image parser
- modules by checking out a recent version of the `mbed TLS Repository`_. It
- is important to use a version that is compatible with TF-A and fixes any
- known security vulnerabilities. See `mbed TLS Security Center`_ for more
- information. The latest version of TF-A is tested with tag
- ``mbedtls-2.16.0``.
-
- The ``drivers/auth/mbedtls/mbedtls_*.mk`` files contain the list of mbed TLS
- source files the modules depend upon.
- ``include/drivers/auth/mbedtls/mbedtls_config.h`` contains the configuration
- options required to build the mbed TLS sources.
-
- Note that the mbed TLS library is licensed under the Apache version 2.0
- license. Using mbed TLS source code will affect the licensing of TF-A
- binaries that are built using this library.
-
-#. To build the FIP image, ensure the following command line variables are set
- while invoking ``make`` to build TF-A:
-
- - ``MBEDTLS_DIR=<path of the directory containing mbed TLS sources>``
- - ``TRUSTED_BOARD_BOOT=1``
- - ``GENERATE_COT=1``
-
- In the case of Arm platforms, the location of the ROTPK hash must also be
- specified at build time. Two locations are currently supported (see
- ``ARM_ROTPK_LOCATION`` build option):
-
- - ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted
- root-key storage registers present in the platform. On Juno, this
- registers are read-only. On FVP Base and Cortex models, the registers
- are read-only, but the value can be specified using the command line
- option ``bp.trusted_key_storage.public_key`` when launching the model.
- On both Juno and FVP models, the default value corresponds to an
- ECDSA-SECP256R1 public key hash, whose private part is not currently
- available.
-
- - ``ARM_ROTPK_LOCATION=devel_rsa``: use the ROTPK hash that is hardcoded
- in the Arm platform port. The private/public RSA key pair may be
- found in ``plat/arm/board/common/rotpk``.
-
- - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the ROTPK hash that is hardcoded
- in the Arm platform port. The private/public ECDSA key pair may be
- found in ``plat/arm/board/common/rotpk``.
-
- Example of command line using RSA development keys:
-
- ::
-
- MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
- make PLAT=<platform> TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \
- ARM_ROTPK_LOCATION=devel_rsa \
- ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
- BL33=<path-to>/<bl33_image> \
- all fip
-
- The result of this build will be the bl1.bin and the fip.bin binaries. This
- FIP will include the certificates corresponding to the Chain of Trust
- described in the TBBR-client document. These certificates can also be found
- in the output build directory.
-
-#. The optional FWU_FIP contains any additional images to be loaded from
- Non-Volatile storage during the `Firmware Update`_ process. To build the
- FWU_FIP, any FWU images required by the platform must be specified on the
- command line. On Arm development platforms like Juno, these are:
-
- - NS_BL2U. The AP non-secure Firmware Updater image.
- - SCP_BL2U. The SCP Firmware Update Configuration image.
-
- Example of Juno command line for generating both ``fwu`` and ``fwu_fip``
- targets using RSA development:
-
- ::
-
- MBEDTLS_DIR=<path of the directory containing mbed TLS sources> \
- make PLAT=juno TRUSTED_BOARD_BOOT=1 GENERATE_COT=1 \
- ARM_ROTPK_LOCATION=devel_rsa \
- ROT_KEY=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem \
- BL33=<path-to>/<bl33_image> \
- SCP_BL2=<path-to>/<scp_bl2_image> \
- SCP_BL2U=<path-to>/<scp_bl2u_image> \
- NS_BL2U=<path-to>/<ns_bl2u_image> \
- all fip fwu_fip
-
- Note: The BL2U image will be built by default and added to the FWU_FIP.
- The user may override this by adding ``BL2U=<path-to>/<bl2u_image>``
- to the command line above.
-
- Note: Building and installing the non-secure and SCP FWU images (NS_BL1U,
- NS_BL2U and SCP_BL2U) is outside the scope of this document.
-
- The result of this build will be bl1.bin, fip.bin and fwu_fip.bin binaries.
- Both the FIP and FWU_FIP will include the certificates corresponding to the
- Chain of Trust described in the TBBR-client document. These certificates
- can also be found in the output build directory.
-
-Building the Certificate Generation Tool
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``cert_create`` tool is built as part of the TF-A build process when the
-``fip`` make target is specified and TBB is enabled (as described in the
-previous section), but it can also be built separately with the following
-command:
-
-::
-
- make PLAT=<platform> [DEBUG=1] [V=1] certtool
-
-For platforms that require their own IDs in certificate files, the generic
-'cert_create' tool can be built with the following command. Note that the target
-platform must define its IDs within a ``platform_oid.h`` header file for the
-build to succeed.
-
-::
-
- make PLAT=<platform> USE_TBBR_DEFS=0 [DEBUG=1] [V=1] certtool
-
-``DEBUG=1`` builds the tool in debug mode. ``V=1`` makes the build process more
-verbose. The following command should be used to obtain help about the tool:
-
-::
-
- ./tools/cert_create/cert_create -h
-
-Building a FIP for Juno and FVP
--------------------------------
-
-This section provides Juno and FVP specific instructions to build Trusted
-Firmware, obtain the additional required firmware, and pack it all together in
-a single FIP binary. It assumes that a `Linaro Release`_ has been installed.
-
-Note: Pre-built binaries for AArch32 are available from Linaro Release 16.12
-onwards. Before that release, pre-built binaries are only available for AArch64.
-
-Note: Follow the full instructions for one platform before switching to a
-different one. Mixing instructions for different platforms may result in
-corrupted binaries.
-
-Note: The uboot image downloaded by the Linaro workspace script does not always
-match the uboot image packaged as BL33 in the corresponding fip file. It is
-recommended to use the version that is packaged in the fip file using the
-instructions below.
-
-Note: For the FVP, the kernel FDT is packaged in FIP during build and loaded
-by the firmware at runtime. See `Obtaining the Flattened Device Trees`_
-section for more info on selecting the right FDT to use.
-
-#. Clean the working directory
-
- ::
-
- make realclean
-
-#. Obtain SCP_BL2 (Juno) and BL33 (all platforms)
-
- Use the fiptool to extract the SCP_BL2 and BL33 images from the FIP
- package included in the Linaro release:
-
- ::
-
- # Build the fiptool
- make [DEBUG=1] [V=1] fiptool
-
- # Unpack firmware images from Linaro FIP
- ./tools/fiptool/fiptool unpack <path-to-linaro-release>/fip.bin
-
- The unpack operation will result in a set of binary images extracted to the
- current working directory. The SCP_BL2 image corresponds to
- ``scp-fw.bin`` and BL33 corresponds to ``nt-fw.bin``.
-
- Note: The fiptool will complain if the images to be unpacked already
- exist in the current directory. If that is the case, either delete those
- files or use the ``--force`` option to overwrite.
-
- Note: For AArch32, the instructions below assume that nt-fw.bin is a normal
- world boot loader that supports AArch32.
-
-#. Build TF-A images and create a new FIP for FVP
-
- ::
-
- # AArch64
- make PLAT=fvp BL33=nt-fw.bin all fip
-
- # AArch32
- make PLAT=fvp ARCH=aarch32 AARCH32_SP=sp_min BL33=nt-fw.bin all fip
-
-#. Build TF-A images and create a new FIP for Juno
-
- For AArch64:
-
- Building for AArch64 on Juno simply requires the addition of ``SCP_BL2``
- as a build parameter.
-
- ::
-
- make PLAT=juno BL33=nt-fw.bin SCP_BL2=scp-fw.bin all fip
-
- For AArch32:
-
- Hardware restrictions on Juno prevent cold reset into AArch32 execution mode,
- therefore BL1 and BL2 must be compiled for AArch64, and BL32 is compiled
- separately for AArch32.
-
- - Before building BL32, the environment variable ``CROSS_COMPILE`` must point
- to the AArch32 Linaro cross compiler.
-
- ::
-
- export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-linux-gnueabihf-
-
- - Build BL32 in AArch32.
-
- ::
-
- make ARCH=aarch32 PLAT=juno AARCH32_SP=sp_min \
- RESET_TO_SP_MIN=1 JUNO_AARCH32_EL3_RUNTIME=1 bl32
-
- - Save ``bl32.bin`` to a temporary location and clean the build products.
-
- ::
-
- cp <path-to-build>/bl32.bin <path-to-temporary>
- make realclean
-
- - Before building BL1 and BL2, the environment variable ``CROSS_COMPILE``
- must point to the AArch64 Linaro cross compiler.
-
- ::
-
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
-
- - The following parameters should be used to build BL1 and BL2 in AArch64
- and point to the BL32 file.
-
- ::
-
- make ARCH=aarch64 PLAT=juno JUNO_AARCH32_EL3_RUNTIME=1 \
- BL33=nt-fw.bin SCP_BL2=scp-fw.bin \
- BL32=<path-to-temporary>/bl32.bin all fip
-
-The resulting BL1 and FIP images may be found in:
-
-::
-
- # Juno
- ./build/juno/release/bl1.bin
- ./build/juno/release/fip.bin
-
- # FVP
- ./build/fvp/release/bl1.bin
- ./build/fvp/release/fip.bin
-
-
-Booting Firmware Update images
--------------------------------------
-
-When Firmware Update (FWU) is enabled there are at least 2 new images
-that have to be loaded, the Non-Secure FWU ROM (NS-BL1U), and the
-FWU FIP.
-
-Juno
-~~~~
-
-The new images must be programmed in flash memory by adding
-an entry in the ``SITE1/HBI0262x/images.txt`` configuration file
-on the Juno SD card (where ``x`` depends on the revision of the Juno board).
-Refer to the `Juno Getting Started Guide`_, section 2.3 "Flash memory
-programming" for more information. User should ensure these do not
-overlap with any other entries in the file.
-
-::
-
- NOR10UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
- NOR10ADDRESS: 0x00400000 ;Image Flash Address [ns_bl2u_base_address]
- NOR10FILE: \SOFTWARE\fwu_fip.bin ;Image File Name
- NOR10LOAD: 00000000 ;Image Load Address
- NOR10ENTRY: 00000000 ;Image Entry Point
-
- NOR11UPDATE: AUTO ;Image Update:NONE/AUTO/FORCE
- NOR11ADDRESS: 0x03EB8000 ;Image Flash Address [ns_bl1u_base_address]
- NOR11FILE: \SOFTWARE\ns_bl1u.bin ;Image File Name
- NOR11LOAD: 00000000 ;Image Load Address
-
-The address ns_bl1u_base_address is the value of NS_BL1U_BASE - 0x8000000.
-In the same way, the address ns_bl2u_base_address is the value of
-NS_BL2U_BASE - 0x8000000.
-
-FVP
-~~~
-
-The additional fip images must be loaded with:
-
-::
-
- --data cluster0.cpu0="<path_to>/ns_bl1u.bin"@0x0beb8000 [ns_bl1u_base_address]
- --data cluster0.cpu0="<path_to>/fwu_fip.bin"@0x08400000 [ns_bl2u_base_address]
-
-The address ns_bl1u_base_address is the value of NS_BL1U_BASE.
-In the same way, the address ns_bl2u_base_address is the value of
-NS_BL2U_BASE.
-
-
-EL3 payloads alternative boot flow
-----------------------------------
-
-On a pre-production system, the ability to execute arbitrary, bare-metal code at
-the highest exception level is required. It allows full, direct access to the
-hardware, for example to run silicon soak tests.
-
-Although it is possible to implement some baremetal secure firmware from
-scratch, this is a complex task on some platforms, depending on the level of
-configuration required to put the system in the expected state.
-
-Rather than booting a baremetal application, a possible compromise is to boot
-``EL3 payloads`` through TF-A instead. This is implemented as an alternative
-boot flow, where a modified BL2 boots an EL3 payload, instead of loading the
-other BL images and passing control to BL31. It reduces the complexity of
-developing EL3 baremetal code by:
-
-- putting the system into a known architectural state;
-- taking care of platform secure world initialization;
-- loading the SCP_BL2 image if required by the platform.
-
-When booting an EL3 payload on Arm standard platforms, the configuration of the
-TrustZone controller is simplified such that only region 0 is enabled and is
-configured to permit secure access only. This gives full access to the whole
-DRAM to the EL3 payload.
-
-The system is left in the same state as when entering BL31 in the default boot
-flow. In particular:
-
-- Running in EL3;
-- Current state is AArch64;
-- Little-endian data access;
-- All exceptions disabled;
-- MMU disabled;
-- Caches disabled.
-
-Booting an EL3 payload
-~~~~~~~~~~~~~~~~~~~~~~
-
-The EL3 payload image is a standalone image and is not part of the FIP. It is
-not loaded by TF-A. Therefore, there are 2 possible scenarios:
-
-- The EL3 payload may reside in non-volatile memory (NVM) and execute in
- place. In this case, booting it is just a matter of specifying the right
- address in NVM through ``EL3_PAYLOAD_BASE`` when building TF-A.
-
-- The EL3 payload needs to be loaded in volatile memory (e.g. DRAM) at
- run-time.
-
-To help in the latter scenario, the ``SPIN_ON_BL1_EXIT=1`` build option can be
-used. The infinite loop that it introduces in BL1 stops execution at the right
-moment for a debugger to take control of the target and load the payload (for
-example, over JTAG).
-
-It is expected that this loading method will work in most cases, as a debugger
-connection is usually available in a pre-production system. The user is free to
-use any other platform-specific mechanism to load the EL3 payload, though.
-
-Booting an EL3 payload on FVP
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The EL3 payloads boot flow requires the CPU's mailbox to be cleared at reset for
-the secondary CPUs holding pen to work properly. Unfortunately, its reset value
-is undefined on the FVP platform and the FVP platform code doesn't clear it.
-Therefore, one must modify the way the model is normally invoked in order to
-clear the mailbox at start-up.
-
-One way to do that is to create an 8-byte file containing all zero bytes using
-the following command:
-
-::
-
- dd if=/dev/zero of=mailbox.dat bs=1 count=8
-
-and pre-load it into the FVP memory at the mailbox address (i.e. ``0x04000000``)
-using the following model parameters:
-
-::
-
- --data cluster0.cpu0=mailbox.dat@0x04000000 [Base FVPs]
- --data=mailbox.dat@0x04000000 [Foundation FVP]
-
-To provide the model with the EL3 payload image, the following methods may be
-used:
-
-#. If the EL3 payload is able to execute in place, it may be programmed into
- flash memory. On Base Cortex and AEM FVPs, the following model parameter
- loads it at the base address of the NOR FLASH1 (the NOR FLASH0 is already
- used for the FIP):
-
- ::
-
- -C bp.flashloader1.fname="<path-to>/<el3-payload>"
-
- On Foundation FVP, there is no flash loader component and the EL3 payload
- may be programmed anywhere in flash using method 3 below.
-
-#. When using the ``SPIN_ON_BL1_EXIT=1`` loading method, the following DS-5
- command may be used to load the EL3 payload ELF image over JTAG:
-
- ::
-
- load <path-to>/el3-payload.elf
-
-#. The EL3 payload may be pre-loaded in volatile memory using the following
- model parameters:
-
- ::
-
- --data cluster0.cpu0="<path-to>/el3-payload>"@address [Base FVPs]
- --data="<path-to>/<el3-payload>"@address [Foundation FVP]
-
- The address provided to the FVP must match the ``EL3_PAYLOAD_BASE`` address
- used when building TF-A.
-
-Booting an EL3 payload on Juno
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-If the EL3 payload is able to execute in place, it may be programmed in flash
-memory by adding an entry in the ``SITE1/HBI0262x/images.txt`` configuration file
-on the Juno SD card (where ``x`` depends on the revision of the Juno board).
-Refer to the `Juno Getting Started Guide`_, section 2.3 "Flash memory
-programming" for more information.
-
-Alternatively, the same DS-5 command mentioned in the FVP section above can
-be used to load the EL3 payload's ELF file over JTAG on Juno.
-
-Preloaded BL33 alternative boot flow
-------------------------------------
-
-Some platforms have the ability to preload BL33 into memory instead of relying
-on TF-A to load it. This may simplify packaging of the normal world code and
-improve performance in a development environment. When secure world cold boot
-is complete, TF-A simply jumps to a BL33 base address provided at build time.
-
-For this option to be used, the ``PRELOADED_BL33_BASE`` build option has to be
-used when compiling TF-A. For example, the following command will create a FIP
-without a BL33 and prepare to jump to a BL33 image loaded at address
-0x80000000:
-
-::
-
- make PRELOADED_BL33_BASE=0x80000000 PLAT=fvp all fip
-
-Boot of a preloaded kernel image on Base FVP
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following example uses a simplified boot flow by directly jumping from the
-TF-A to the Linux kernel, which will use a ramdisk as filesystem. This can be
-useful if both the kernel and the device tree blob (DTB) are already present in
-memory (like in FVP).
-
-For example, if the kernel is loaded at ``0x80080000`` and the DTB is loaded at
-address ``0x82000000``, the firmware can be built like this:
-
-::
-
- CROSS_COMPILE=aarch64-linux-gnu- \
- make PLAT=fvp DEBUG=1 \
- RESET_TO_BL31=1 \
- ARM_LINUX_KERNEL_AS_BL33=1 \
- PRELOADED_BL33_BASE=0x80080000 \
- ARM_PRELOADED_DTB_BASE=0x82000000 \
- all fip
-
-Now, it is needed to modify the DTB so that the kernel knows the address of the
-ramdisk. The following script generates a patched DTB from the provided one,
-assuming that the ramdisk is loaded at address ``0x84000000``. Note that this
-script assumes that the user is using a ramdisk image prepared for U-Boot, like
-the ones provided by Linaro. If using a ramdisk without this header,the ``0x40``
-offset in ``INITRD_START`` has to be removed.
-
-.. code:: bash
-
- #!/bin/bash
-
- # Path to the input DTB
- KERNEL_DTB=<path-to>/<fdt>
- # Path to the output DTB
- PATCHED_KERNEL_DTB=<path-to>/<patched-fdt>
- # Base address of the ramdisk
- INITRD_BASE=0x84000000
- # Path to the ramdisk
- INITRD=<path-to>/<ramdisk.img>
-
- # Skip uboot header (64 bytes)
- INITRD_START=$(printf "0x%x" $((${INITRD_BASE} + 0x40)) )
- INITRD_SIZE=$(stat -Lc %s ${INITRD})
- INITRD_END=$(printf "0x%x" $((${INITRD_BASE} + ${INITRD_SIZE})) )
-
- CHOSEN_NODE=$(echo \
- "/ { \
- chosen { \
- linux,initrd-start = <${INITRD_START}>; \
- linux,initrd-end = <${INITRD_END}>; \
- }; \
- };")
-
- echo $(dtc -O dts -I dtb ${KERNEL_DTB}) ${CHOSEN_NODE} | \
- dtc -O dtb -o ${PATCHED_KERNEL_DTB} -
-
-And the FVP binary can be run with the following command:
-
-::
-
- <path-to>/FVP_Base_AEMv8A-AEMv8A \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C cluster0.NUM_CORES=4 \
- -C cluster1.NUM_CORES=4 \
- -C cache_state_modelled=1 \
- -C cluster0.cpu0.RVBAR=0x04020000 \
- -C cluster0.cpu1.RVBAR=0x04020000 \
- -C cluster0.cpu2.RVBAR=0x04020000 \
- -C cluster0.cpu3.RVBAR=0x04020000 \
- -C cluster1.cpu0.RVBAR=0x04020000 \
- -C cluster1.cpu1.RVBAR=0x04020000 \
- -C cluster1.cpu2.RVBAR=0x04020000 \
- -C cluster1.cpu3.RVBAR=0x04020000 \
- --data cluster0.cpu0="<path-to>/bl31.bin"@0x04020000 \
- --data cluster0.cpu0="<path-to>/<patched-fdt>"@0x82000000 \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk.img>"@0x84000000
-
-Boot of a preloaded kernel image on Juno
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The Trusted Firmware must be compiled in a similar way as for FVP explained
-above. The process to load binaries to memory is the one explained in
-`Booting an EL3 payload on Juno`_.
-
-Running the software on FVP
----------------------------
-
-The latest version of the AArch64 build of TF-A has been tested on the following
-Arm FVPs without shifted affinities, and that do not support threaded CPU cores
-(64-bit host machine only).
-
-The FVP models used are Version 11.6 Build 45, unless otherwise stated.
-
-- ``FVP_Base_AEMv8A-AEMv8A``
-- ``FVP_Base_AEMv8A-AEMv8A-AEMv8A-AEMv8A-CCN502``
-- ``FVP_Base_RevC-2xAEMv8A``
-- ``FVP_Base_Cortex-A32x4``
-- ``FVP_Base_Cortex-A35x4``
-- ``FVP_Base_Cortex-A53x4``
-- ``FVP_Base_Cortex-A55x4+Cortex-A75x4``
-- ``FVP_Base_Cortex-A55x4``
-- ``FVP_Base_Cortex-A57x1-A53x1``
-- ``FVP_Base_Cortex-A57x2-A53x4``
-- ``FVP_Base_Cortex-A57x4-A53x4``
-- ``FVP_Base_Cortex-A57x4``
-- ``FVP_Base_Cortex-A72x4-A53x4``
-- ``FVP_Base_Cortex-A72x4``
-- ``FVP_Base_Cortex-A73x4-A53x4``
-- ``FVP_Base_Cortex-A73x4``
-- ``FVP_Base_Cortex-A75x4``
-- ``FVP_Base_Cortex-A76x4``
-- ``FVP_Base_Cortex-A76AEx4``
-- ``FVP_Base_Cortex-A76AEx8``
-- ``FVP_Base_Neoverse-N1x4``
-- ``FVP_Base_Deimos``
-- ``FVP_CSS_SGI-575`` (Version 11.3 build 42)
-- ``FVP_CSS_SGM-775`` (Version 11.3 build 42)
-- ``FVP_RD_E1Edge`` (Version 11.3 build 42)
-- ``FVP_RD_N1Edge``
-- ``Foundation_Platform``
-
-The latest version of the AArch32 build of TF-A has been tested on the following
-Arm FVPs without shifted affinities, and that do not support threaded CPU cores
-(64-bit host machine only).
-
-- ``FVP_Base_AEMv8A-AEMv8A``
-- ``FVP_Base_Cortex-A32x4``
-
-NOTE: The ``FVP_Base_RevC-2xAEMv8A`` FVP only supports shifted affinities, which
-is not compatible with legacy GIC configurations. Therefore this FVP does not
-support these legacy GIC configurations.
-
-NOTE: The build numbers quoted above are those reported by launching the FVP
-with the ``--version`` parameter.
-
-NOTE: Linaro provides a ramdisk image in prebuilt FVP configurations and full
-file systems that can be downloaded separately. To run an FVP with a virtio
-file system image an additional FVP configuration option
-``-C bp.virtioblockdevice.image_path="<path-to>/<file-system-image>`` can be
-used.
-
-NOTE: The software will not work on Version 1.0 of the Foundation FVP.
-The commands below would report an ``unhandled argument`` error in this case.
-
-NOTE: FVPs can be launched with ``--cadi-server`` option such that a
-CADI-compliant debugger (for example, Arm DS-5) can connect to and control its
-execution.
-
-NOTE: Since FVP model Version 11.0 Build 11.0.34 and Version 8.5 Build 0.8.5202
-the internal synchronisation timings changed compared to older versions of the
-models. The models can be launched with ``-Q 100`` option if they are required
-to match the run time characteristics of the older versions.
-
-The Foundation FVP is a cut down version of the AArch64 Base FVP. It can be
-downloaded for free from `Arm's website`_.
-
-The Cortex-A models listed above are also available to download from
-`Arm's website`_.
-
-Please refer to the FVP documentation for a detailed description of the model
-parameter options. A brief description of the important ones that affect TF-A
-and normal world software behavior is provided below.
-
-Obtaining the Flattened Device Trees
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Depending on the FVP configuration and Linux configuration used, different
-FDT files are required. FDT source files for the Foundation and Base FVPs can
-be found in the TF-A source directory under ``fdts/``. The Foundation FVP has
-a subset of the Base FVP components. For example, the Foundation FVP lacks
-CLCD and MMC support, and has only one CPU cluster.
-
-Note: It is not recommended to use the FDTs built along the kernel because not
-all FDTs are available from there.
-
-The dynamic configuration capability is enabled in the firmware for FVPs.
-This means that the firmware can authenticate and load the FDT if present in
-FIP. A default FDT is packaged into FIP during the build based on
-the build configuration. This can be overridden by using the ``FVP_HW_CONFIG``
-or ``FVP_HW_CONFIG_DTS`` build options (refer to the
-`Arm FVP platform specific build options`_ section for detail on the options).
-
-- ``fvp-base-gicv2-psci.dts``
-
- For use with models such as the Cortex-A57-A53 Base FVPs without shifted
- affinities and with Base memory map configuration.
-
-- ``fvp-base-gicv2-psci-aarch32.dts``
-
- For use with models such as the Cortex-A32 Base FVPs without shifted
- affinities and running Linux in AArch32 state with Base memory map
- configuration.
-
-- ``fvp-base-gicv3-psci.dts``
-
- For use with models such as the Cortex-A57-A53 Base FVPs without shifted
- affinities and with Base memory map configuration and Linux GICv3 support.
-
-- ``fvp-base-gicv3-psci-1t.dts``
-
- For use with models such as the AEMv8-RevC Base FVP with shifted affinities,
- single threaded CPUs, Base memory map configuration and Linux GICv3 support.
-
-- ``fvp-base-gicv3-psci-dynamiq.dts``
-
- For use with models as the Cortex-A55-A75 Base FVPs with shifted affinities,
- single cluster, single threaded CPUs, Base memory map configuration and Linux
- GICv3 support.
-
-- ``fvp-base-gicv3-psci-aarch32.dts``
-
- For use with models such as the Cortex-A32 Base FVPs without shifted
- affinities and running Linux in AArch32 state with Base memory map
- configuration and Linux GICv3 support.
-
-- ``fvp-foundation-gicv2-psci.dts``
-
- For use with Foundation FVP with Base memory map configuration.
-
-- ``fvp-foundation-gicv3-psci.dts``
-
- (Default) For use with Foundation FVP with Base memory map configuration
- and Linux GICv3 support.
-
-Running on the Foundation FVP with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``Foundation_Platform`` parameters should be used to boot Linux with
-4 CPUs using the AArch64 build of TF-A.
-
-::
-
- <path-to>/Foundation_Platform \
- --cores=4 \
- --arm-v8.0 \
- --secure-memory \
- --visualization \
- --gicv3 \
- --data="<path-to>/<bl1-binary>"@0x0 \
- --data="<path-to>/<FIP-binary>"@0x08000000 \
- --data="<path-to>/<kernel-binary>"@0x80080000 \
- --data="<path-to>/<ramdisk-binary>"@0x84000000
-
-Notes:
-
-- BL1 is loaded at the start of the Trusted ROM.
-- The Firmware Image Package is loaded at the start of NOR FLASH0.
-- The firmware loads the FDT packaged in FIP to the DRAM. The FDT load address
- is specified via the ``hw_config_addr`` property in `TB_FW_CONFIG for FVP`_.
-- The default use-case for the Foundation FVP is to use the ``--gicv3`` option
- and enable the GICv3 device in the model. Note that without this option,
- the Foundation FVP defaults to legacy (Versatile Express) memory map which
- is not supported by TF-A.
-- In order for TF-A to run correctly on the Foundation FVP, the architecture
- versions must match. The Foundation FVP defaults to the highest v8.x
- version it supports but the default build for TF-A is for v8.0. To avoid
- issues either start the Foundation FVP to use v8.0 architecture using the
- ``--arm-v8.0`` option, or build TF-A with an appropriate value for
- ``ARM_ARCH_MINOR``.
-
-Running on the AEMv8 Base FVP with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch64 build of TF-A.
-
-::
-
- <path-to>/FVP_Base_RevC-2xAEMv8A \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C bp.tzc_400.diagnostics=1 \
- -C cluster0.NUM_CORES=4 \
- -C cluster1.NUM_CORES=4 \
- -C cache_state_modelled=1 \
- -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
- -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Note: The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
-specific DTS for all the CPUs to be loaded.
-
-Running on the AEMv8 Base FVP (AArch32) with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch32 build of TF-A.
-
-::
-
- <path-to>/FVP_Base_AEMv8A-AEMv8A \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C bp.tzc_400.diagnostics=1 \
- -C cluster0.NUM_CORES=4 \
- -C cluster1.NUM_CORES=4 \
- -C cache_state_modelled=1 \
- -C cluster0.cpu0.CONFIG64=0 \
- -C cluster0.cpu1.CONFIG64=0 \
- -C cluster0.cpu2.CONFIG64=0 \
- -C cluster0.cpu3.CONFIG64=0 \
- -C cluster1.cpu0.CONFIG64=0 \
- -C cluster1.cpu1.CONFIG64=0 \
- -C cluster1.cpu2.CONFIG64=0 \
- -C cluster1.cpu3.CONFIG64=0 \
- -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
- -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A57-A53 Base FVP with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
-boot Linux with 8 CPUs using the AArch64 build of TF-A.
-
-::
-
- <path-to>/FVP_Base_Cortex-A57x4-A53x4 \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C bp.tzc_400.diagnostics=1 \
- -C cache_state_modelled=1 \
- -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
- -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A32 Base FVP (AArch32) with reset to BL1 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
-boot Linux with 4 CPUs using the AArch32 build of TF-A.
-
-::
-
- <path-to>/FVP_Base_Cortex-A32x4 \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C bp.tzc_400.diagnostics=1 \
- -C cache_state_modelled=1 \
- -C bp.secureflashloader.fname="<path-to>/<bl1-binary>" \
- -C bp.flashloader0.fname="<path-to>/<FIP-binary>" \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the AEMv8 Base FVP with reset to BL31 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_RevC-2xAEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch64 build of TF-A.
-
-::
-
- <path-to>/FVP_Base_RevC-2xAEMv8A \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C bp.tzc_400.diagnostics=1 \
- -C cluster0.NUM_CORES=4 \
- -C cluster1.NUM_CORES=4 \
- -C cache_state_modelled=1 \
- -C cluster0.cpu0.RVBAR=0x04010000 \
- -C cluster0.cpu1.RVBAR=0x04010000 \
- -C cluster0.cpu2.RVBAR=0x04010000 \
- -C cluster0.cpu3.RVBAR=0x04010000 \
- -C cluster1.cpu0.RVBAR=0x04010000 \
- -C cluster1.cpu1.RVBAR=0x04010000 \
- -C cluster1.cpu2.RVBAR=0x04010000 \
- -C cluster1.cpu3.RVBAR=0x04010000 \
- --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000 \
- --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000 \
- --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
- --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000 \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Notes:
-
-- If Position Independent Executable (PIE) support is enabled for BL31
- in this config, it can be loaded at any valid address for execution.
-
-- Since a FIP is not loaded when using BL31 as reset entrypoint, the
- ``--data="<path-to><bl31|bl32|bl33-binary>"@<base-address-of-binary>``
- parameter is needed to load the individual bootloader images in memory.
- BL32 image is only needed if BL31 has been built to expect a Secure-EL1
- Payload. For the same reason, the FDT needs to be compiled from the DT source
- and loaded via the ``--data cluster0.cpu0="<path-to>/<fdt>"@0x82000000``
- parameter.
-
-- The ``FVP_Base_RevC-2xAEMv8A`` has shifted affinities and requires a
- specific DTS for all the CPUs to be loaded.
-
-- The ``-C cluster<X>.cpu<Y>.RVBAR=@<base-address-of-bl31>`` parameter, where
- X and Y are the cluster and CPU numbers respectively, is used to set the
- reset vector for each core.
-
-- Changing the default value of ``ARM_TSP_RAM_LOCATION`` will also require
- changing the value of
- ``--data="<path-to><bl32-binary>"@<base-address-of-bl32>`` to the new value of
- ``BL32_BASE``.
-
-Running on the AEMv8 Base FVP (AArch32) with reset to SP_MIN entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_AEMv8A-AEMv8A`` parameters should be used to boot Linux
-with 8 CPUs using the AArch32 build of TF-A.
-
-::
-
- <path-to>/FVP_Base_AEMv8A-AEMv8A \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C bp.tzc_400.diagnostics=1 \
- -C cluster0.NUM_CORES=4 \
- -C cluster1.NUM_CORES=4 \
- -C cache_state_modelled=1 \
- -C cluster0.cpu0.CONFIG64=0 \
- -C cluster0.cpu1.CONFIG64=0 \
- -C cluster0.cpu2.CONFIG64=0 \
- -C cluster0.cpu3.CONFIG64=0 \
- -C cluster1.cpu0.CONFIG64=0 \
- -C cluster1.cpu1.CONFIG64=0 \
- -C cluster1.cpu2.CONFIG64=0 \
- -C cluster1.cpu3.CONFIG64=0 \
- -C cluster0.cpu0.RVBAR=0x04002000 \
- -C cluster0.cpu1.RVBAR=0x04002000 \
- -C cluster0.cpu2.RVBAR=0x04002000 \
- -C cluster0.cpu3.RVBAR=0x04002000 \
- -C cluster1.cpu0.RVBAR=0x04002000 \
- -C cluster1.cpu1.RVBAR=0x04002000 \
- -C cluster1.cpu2.RVBAR=0x04002000 \
- -C cluster1.cpu3.RVBAR=0x04002000 \
- --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000 \
- --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
- --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000 \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Note: The load address of ``<bl32-binary>`` depends on the value ``BL32_BASE``.
-It should match the address programmed into the RVBAR register as well.
-
-Running on the Cortex-A57-A53 Base FVP with reset to BL31 entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_Cortex-A57x4-A53x4`` model parameters should be used to
-boot Linux with 8 CPUs using the AArch64 build of TF-A.
-
-::
-
- <path-to>/FVP_Base_Cortex-A57x4-A53x4 \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C bp.tzc_400.diagnostics=1 \
- -C cache_state_modelled=1 \
- -C cluster0.cpu0.RVBARADDR=0x04010000 \
- -C cluster0.cpu1.RVBARADDR=0x04010000 \
- -C cluster0.cpu2.RVBARADDR=0x04010000 \
- -C cluster0.cpu3.RVBARADDR=0x04010000 \
- -C cluster1.cpu0.RVBARADDR=0x04010000 \
- -C cluster1.cpu1.RVBARADDR=0x04010000 \
- -C cluster1.cpu2.RVBARADDR=0x04010000 \
- -C cluster1.cpu3.RVBARADDR=0x04010000 \
- --data cluster0.cpu0="<path-to>/<bl31-binary>"@0x04010000 \
- --data cluster0.cpu0="<path-to>/<bl32-binary>"@0xff000000 \
- --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
- --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000 \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running on the Cortex-A32 Base FVP (AArch32) with reset to SP_MIN entrypoint
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The following ``FVP_Base_Cortex-A32x4`` model parameters should be used to
-boot Linux with 4 CPUs using the AArch32 build of TF-A.
-
-::
-
- <path-to>/FVP_Base_Cortex-A32x4 \
- -C pctl.startup=0.0.0.0 \
- -C bp.secure_memory=1 \
- -C bp.tzc_400.diagnostics=1 \
- -C cache_state_modelled=1 \
- -C cluster0.cpu0.RVBARADDR=0x04002000 \
- -C cluster0.cpu1.RVBARADDR=0x04002000 \
- -C cluster0.cpu2.RVBARADDR=0x04002000 \
- -C cluster0.cpu3.RVBARADDR=0x04002000 \
- --data cluster0.cpu0="<path-to>/<bl32-binary>"@0x04002000 \
- --data cluster0.cpu0="<path-to>/<bl33-binary>"@0x88000000 \
- --data cluster0.cpu0="<path-to>/<fdt>"@0x82000000 \
- --data cluster0.cpu0="<path-to>/<kernel-binary>"@0x80080000 \
- --data cluster0.cpu0="<path-to>/<ramdisk>"@0x84000000
-
-Running the software on Juno
-----------------------------
-
-This version of TF-A has been tested on variants r0, r1 and r2 of Juno.
-
-To execute the software stack on Juno, the version of the Juno board recovery
-image indicated in the `Linaro Release Notes`_ must be installed. If you have an
-earlier version installed or are unsure which version is installed, please
-re-install the recovery image by following the
-`Instructions for using Linaro's deliverables on Juno`_.
-
-Preparing TF-A images
-~~~~~~~~~~~~~~~~~~~~~
-
-After building TF-A, the files ``bl1.bin`` and ``fip.bin`` need copying to the
-``SOFTWARE/`` directory of the Juno SD card.
-
-Other Juno software information
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Please visit the `Arm Platforms Portal`_ to get support and obtain any other Juno
-software information. Please also refer to the `Juno Getting Started Guide`_ to
-get more detailed information about the Juno Arm development platform and how to
-configure it.
-
-Testing SYSTEM SUSPEND on Juno
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The SYSTEM SUSPEND is a PSCI API which can be used to implement system suspend
-to RAM. For more details refer to section 5.16 of `PSCI`_. To test system suspend
-on Juno, at the linux shell prompt, issue the following command:
-
-::
-
- echo +10 > /sys/class/rtc/rtc0/wakealarm
- echo -n mem > /sys/power/state
-
-The Juno board should suspend to RAM and then wakeup after 10 seconds due to
-wakeup interrupt from RTC.
-
---------------
-
-*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
-
-.. _arm Developer page: https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads
-.. _Linaro: `Linaro Release Notes`_
-.. _Linaro Release: `Linaro Release Notes`_
-.. _Linaro Release Notes: https://community.arm.com/dev-platforms/w/docs/226/old-release-notes
-.. _Linaro instructions: https://community.arm.com/dev-platforms/w/docs/304/arm-reference-platforms-deliverables
-.. _Instructions for using Linaro's deliverables on Juno: https://community.arm.com/dev-platforms/w/docs/303/juno
-.. _Arm Platforms Portal: https://community.arm.com/dev-platforms/
-.. _Development Studio 5 (DS-5): https://developer.arm.com/products/software-development-tools/ds-5-development-studio
-.. _arm-trusted-firmware-a project page: https://review.trustedfirmware.org/admin/projects/TF-A/trusted-firmware-a
-.. _`Linux Coding Style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
-.. _Linux master tree: https://github.com/torvalds/linux/tree/master/
-.. _Dia: https://wiki.gnome.org/Apps/Dia/Download
-.. _here: psci-lib-integration-guide.rst
-.. _Trusted Board Boot: trusted-board-boot.rst
-.. _TB_FW_CONFIG for FVP: ../plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
-.. _Secure-EL1 Payloads and Dispatchers: firmware-design.rst#user-content-secure-el1-payloads-and-dispatchers
-.. _Firmware Update: firmware-update.rst
-.. _Firmware Design: firmware-design.rst
-.. _mbed TLS Repository: https://github.com/ARMmbed/mbedtls.git
-.. _mbed TLS Security Center: https://tls.mbed.org/security
-.. _Arm's website: `FVP models`_
-.. _FVP models: https://developer.arm.com/products/system-design/fixed-virtual-platforms
-.. _Juno Getting Started Guide: http://infocenter.arm.com/help/topic/com.arm.doc.dui0928e/DUI0928E_juno_arm_development_platform_gsg.pdf
-.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
-.. _Secure Partition Manager Design guide: secure-partition-manager-design.rst
-.. _`Trusted Firmware-A Coding Guidelines`: coding-guidelines.rst
-.. _`Library at ROM`: romlib-design.rst
+++ /dev/null
-Translation Tables Library Design
-=================================
-
-
-.. section-numbering::
- :suffix: .
-
-.. contents::
-
-
-This document describes the design of the translation tables library (version 2)
-used by Trusted Firmware-A (TF-A). This library provides APIs to create page
-tables based on a description of the memory layout, as well as setting up system
-registers related to the Memory Management Unit (MMU) and performing the
-required Translation Lookaside Buffer (TLB) maintenance operations.
-
-More specifically, some use cases that this library aims to support are:
-
-#. Statically allocate translation tables and populate them (at run-time) based
- on a description of the memory layout. The memory layout is typically
- provided by the platform port as a list of memory regions;
-
-#. Support for generating translation tables pertaining to a different
- translation regime than the exception level the library code is executing at;
-
-#. Support for dynamic mapping and unmapping of regions, even while the MMU is
- on. This can be used to temporarily map some memory regions and unmap them
- later on when no longer needed;
-
-#. Support for non-identity virtual to physical mappings to compress the virtual
- address space;
-
-#. Support for changing memory attributes of memory regions at run-time.
-
-
-About version 1 and version 2
------------------------------
-
-This document focuses on version 2 of the library, whose sources are available
-in the `lib/xlat_tables_v2`_ directory. Version 1 of the library can still be
-found in `lib/xlat_tables`_ directory but it is less flexible and doesn't
-support dynamic mapping. Although potential bug fixes will be applied to both
-versions, future features enhancements will focus on version 2 and might not be
-back-ported to version 1. Therefore, it is recommended to use version 2,
-especially for new platform ports.
-
-However, please note that version 2 is still in active development and is not
-considered stable yet. Hence, compatibility breaks might be introduced.
-
-From this point onwards, this document will implicitly refer to version 2 of the
-library.
-
-
-Design concepts and interfaces
-------------------------------
-
-This section presents some of the key concepts and data structures used in the
-translation tables library.
-
-`mmap` regions
-~~~~~~~~~~~~~~
-
-An ``mmap_region`` is an abstract, concise way to represent a memory region to
-map. It is one of the key interfaces to the library. It is identified by:
-
-- its physical base address;
-- its virtual base address;
-- its size;
-- its attributes;
-- its mapping granularity (optional).
-
-See the ``struct mmap_region`` type in `xlat_tables_v2.h`_.
-
-The user usually provides a list of such mmap regions to map and lets the
-library transpose that in a set of translation tables. As a result, the library
-might create new translation tables, update or split existing ones.
-
-The region attributes specify the type of memory (for example device or cached
-normal memory) as well as the memory access permissions (read-only or
-read-write, executable or not, secure or non-secure, and so on). In the case of
-the EL1&0 translation regime, the attributes also specify whether the region is
-a User region (EL0) or Privileged region (EL1). See the ``MT_xxx`` definitions
-in `xlat_tables_v2.h`_. Note that for the EL1&0 translation regime the Execute
-Never attribute is set simultaneously for both EL1 and EL0.
-
-The granularity controls the translation table level to go down to when mapping
-the region. For example, assuming the MMU has been configured to use a 4KB
-granule size, the library might map a 2MB memory region using either of the two
-following options:
-
-- using a single level-2 translation table entry;
-- using a level-2 intermediate entry to a level-3 translation table (which
- contains 512 entries, each mapping 4KB).
-
-The first solution potentially requires less translation tables, hence
-potentially less memory. However, if part of this 2MB region is later remapped
-with different memory attributes, the library might need to split the existing
-page tables to refine the mappings. If a single level-2 entry has been used
-here, a level-3 table will need to be allocated on the fly and the level-2
-modified to point to this new level-3 table. This has a performance cost at
-run-time.
-
-If the user knows upfront that such a remapping operation is likely to happen
-then they might enforce a 4KB mapping granularity for this 2MB region from the
-beginning; remapping some of these 4KB pages on the fly then becomes a
-lightweight operation.
-
-The region's granularity is an optional field; if it is not specified the
-library will choose the mapping granularity for this region as it sees fit (more
-details can be found in `The memory mapping algorithm`_ section below).
-
-Translation Context
-~~~~~~~~~~~~~~~~~~~
-
-The library can create or modify translation tables pertaining to a different
-translation regime than the exception level the library code is executing at.
-For example, the library might be used by EL3 software (for instance BL31) to
-create translation tables pertaining to the S-EL1&0 translation regime.
-
-This flexibility comes from the use of *translation contexts*. A *translation
-context* constitutes the superset of information used by the library to track
-the status of a set of translation tables for a given translation regime.
-
-The library internally allocates a default translation context, which pertains
-to the translation regime of the current exception level. Additional contexts
-may be explicitly allocated and initialized using the
-``REGISTER_XLAT_CONTEXT()`` macro. Separate APIs are provided to act either on
-the default translation context or on an alternative one.
-
-To register a translation context, the user must provide the library with the
-following information:
-
-* A name.
-
- The resulting translation context variable will be called after this name, to
- which ``_xlat_ctx`` is appended. For example, if the macro name parameter is
- ``foo``, the context variable name will be ``foo_xlat_ctx``.
-
-* The maximum number of `mmap` regions to map.
-
- Should account for both static and dynamic regions, if applicable.
-
-* The number of sub-translation tables to allocate.
-
- Number of translation tables to statically allocate for this context,
- excluding the initial lookup level translation table, which is always
- allocated. For example, if the initial lookup level is 1, this parameter would
- specify the number of level-2 and level-3 translation tables to pre-allocate
- for this context.
-
-* The size of the virtual address space.
-
- Size in bytes of the virtual address space to map using this context. This
- will incidentally determine the number of entries in the initial lookup level
- translation table : the library will allocate as many entries as is required
- to map the entire virtual address space.
-
-* The size of the physical address space.
-
- Size in bytes of the physical address space to map using this context.
-
-The default translation context is internally initialized using information
-coming (for the most part) from platform-specific defines:
-
-- name: hard-coded to ``tf`` ; hence the name of the default context variable is
- ``tf_xlat_ctx``;
-- number of `mmap` regions: ``MAX_MMAP_REGIONS``;
-- number of sub-translation tables: ``MAX_XLAT_TABLES``;
-- size of the virtual address space: ``PLAT_VIRT_ADDR_SPACE_SIZE``;
-- size of the physical address space: ``PLAT_PHY_ADDR_SPACE_SIZE``.
-
-Please refer to the `Porting Guide`_ for more details about these macros.
-
-
-Static and dynamic memory regions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The library optionally supports dynamic memory mapping. This feature may be
-enabled using the ``PLAT_XLAT_TABLES_DYNAMIC`` platform build flag.
-
-When dynamic memory mapping is enabled, the library categorises mmap regions as
-*static* or *dynamic*.
-
-- *Static regions* are fixed for the lifetime of the system. They can only be
- added early on, before the translation tables are created and populated. They
- cannot be removed afterwards.
-
-- *Dynamic regions* can be added or removed any time.
-
-When the dynamic memory mapping feature is disabled, only static regions exist.
-
-The dynamic memory mapping feature may be used to map and unmap transient memory
-areas. This is useful when the user needs to access some memory for a fixed
-period of time, after which the memory may be discarded and reclaimed. For
-example, a memory region that is only required at boot time while the system is
-initializing, or to temporarily share a memory buffer between the normal world
-and trusted world. Note that it is up to the caller to ensure that these regions
-are not accessed concurrently while the regions are being added or removed.
-
-Although this feature provides some level of dynamic memory allocation, this
-does not allow dynamically allocating an arbitrary amount of memory at an
-arbitrary memory location. The user is still required to declare at compile-time
-the limits of these allocations ; the library will deny any mapping request that
-does not fit within this pre-allocated pool of memory.
-
-
-Library APIs
-------------
-
-The external APIs exposed by this library are declared and documented in the
-`xlat_tables_v2.h`_ header file. This should be the reference point for
-getting information about the usage of the different APIs this library
-provides. This section just provides some extra details and clarifications.
-
-Although the ``mmap_region`` structure is a publicly visible type, it is not
-recommended to populate these structures by hand. Instead, wherever APIs expect
-function arguments of type ``mmap_region_t``, these should be constructed using
-the ``MAP_REGION*()`` family of helper macros. This is to limit the risk of
-compatibility breaks, should the ``mmap_region`` structure type evolve in the
-future.
-
-The ``MAP_REGION()`` and ``MAP_REGION_FLAT()`` macros do not allow specifying a
-mapping granularity, which leaves the library implementation free to choose
-it. However, in cases where a specific granularity is required, the
-``MAP_REGION2()`` macro might be used instead.
-
-As explained earlier in this document, when the dynamic mapping feature is
-disabled, there is no notion of dynamic regions. Conceptually, there are only
-static regions. For this reason (and to retain backward compatibility with the
-version 1 of the library), the APIs that map static regions do not embed the
-word *static* in their functions names (for example ``mmap_add_region()``), in
-contrast with the dynamic regions APIs (for example
-``mmap_add_dynamic_region()``).
-
-Although the definition of static and dynamic regions is not based on the state
-of the MMU, the two are still related in some way. Static regions can only be
-added before ``init_xlat_tables()`` is called and ``init_xlat_tables()`` must be
-called while the MMU is still off. As a result, static regions cannot be added
-once the MMU has been enabled. Dynamic regions can be added with the MMU on or
-off. In practice, the usual call flow would look like this:
-
-#. The MMU is initially off.
-
-#. Add some static regions, add some dynamic regions.
-
-#. Initialize translation tables based on the list of mmap regions (using one of
- the ``init_xlat_tables*()`` APIs).
-
-#. At this point, it is no longer possible to add static regions. Dynamic
- regions can still be added or removed.
-
-#. Enable the MMU.
-
-#. Dynamic regions can continue to be added or removed.
-
-Because static regions are added early on at boot time and are all in the
-control of the platform initialization code, the ``mmap_add*()`` family of APIs
-are not expected to fail. They do not return any error code.
-
-Nonetheless, these APIs will check upfront whether the region can be
-successfully added before updating the translation context structure. If the
-library detects that there is insufficient memory to meet the request, or that
-the new region will overlap another one in an invalid way, or if any other
-unexpected error is encountered, they will print an error message on the UART.
-Additionally, when asserts are enabled (typically in debug builds), an assertion
-will be triggered. Otherwise, the function call will just return straight away,
-without adding the offending memory region.
-
-
-Library limitations
--------------------
-
-Dynamic regions are not allowed to overlap each other. Static regions are
-allowed to overlap as long as one of them is fully contained inside the other
-one. This is allowed for backwards compatibility with the previous behaviour in
-the version 1 of the library.
-
-
-Implementation details
-----------------------
-
-Code structure
-~~~~~~~~~~~~~~
-
-The library is divided into 4 modules:
-
-- **Core module**
-
- Provides the main functionality of the library, such as the initialization of
- translation tables contexts and mapping/unmapping memory regions. This module
- provides functions such as ``mmap_add_region_ctx`` that let the caller specify
- the translation tables context affected by them.
-
- See `xlat_tables_core.c`_.
-
-- **Active context module**
-
- Instantiates the context that is used by the current BL image and provides
- helpers to manipulate it, abstracting it from the rest of the code.
- This module provides functions such as ``mmap_add_region``, that directly
- affect the BL image using them.
-
- See `xlat_tables_context.c`_.
-
-- **Utilities module**
-
- Provides additional functionality like debug print of the current state of the
- translation tables and helpers to query memory attributes and to modify them.
-
- See `xlat_tables_utils.c`_.
-
-- **Architectural module**
-
- Provides functions that are dependent on the current execution state
- (AArch32/AArch64), such as the functions used for TLB invalidation, setup the
- MMU, or calculate the Physical Address Space size. They do not need a
- translation context to work on.
-
- See `aarch32/xlat_tables_arch.c`_ and `aarch64/xlat_tables_arch.c`_.
-
-From mmap regions to translation tables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A translation context contains a list of ``mmap_region_t``, which holds the
-information of all the regions that are mapped at any given time. Whenever there
-is a request to map (resp. unmap) a memory region, it is added to (resp. removed
-from) the ``mmap_region_t`` list.
-
-The mmap regions list is a conceptual way to represent the memory layout. At
-some point, the library has to convert this information into actual translation
-tables to program into the MMU.
-
-Before the ``init_xlat_tables()`` API is called, the library only acts on the
-mmap regions list. Adding a static or dynamic region at this point through one
-of the ``mmap_add*()`` APIs does not affect the translation tables in any way,
-they only get registered in the internal mmap region list. It is only when the
-user calls the ``init_xlat_tables()`` that the translation tables are populated
-in memory based on the list of mmap regions registered so far. This is an
-optimization that allows creation of the initial set of translation tables in
-one go, rather than having to edit them every time while the MMU is disabled.
-
-After the ``init_xlat_tables()`` API has been called, only dynamic regions can
-be added. Changes to the translation tables (as well as the mmap regions list)
-will take effect immediately.
-
-The memory mapping algorithm
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The mapping function is implemented as a recursive algorithm. It is however
-bound by the level of depth of the translation tables (the Armv8-A architecture
-allows up to 4 lookup levels).
-
-By default [#granularity-ref]_, the algorithm will attempt to minimize the
-number of translation tables created to satisfy the user's request. It will
-favour mapping a region using the biggest possible blocks, only creating a
-sub-table if it is strictly necessary. This is to reduce the memory footprint of
-the firmware.
-
-The most common reason for needing a sub-table is when a specific mapping
-requires a finer granularity. Misaligned regions also require a finer
-granularity than what the user may had originally expected, using a lot more
-memory than expected. The reason is that all levels of translation are
-restricted to address translations of the same granularity as the size of the
-blocks of that level. For example, for a 4 KiB page size, a level 2 block entry
-can only translate up to a granularity of 2 MiB. If the Physical Address is not
-aligned to 2 MiB then additional level 3 tables are also needed.
-
-Note that not every translation level allows any type of descriptor. Depending
-on the page size, levels 0 and 1 of translation may only allow table
-descriptors. If a block entry could be able to describe a translation, but that
-level does not allow block descriptors, a table descriptor will have to be used
-instead, as well as additional tables at the next level.
-
-|Alignment Example|
-
-The mmap regions are sorted in a way that simplifies the code that maps
-them. Even though this ordering is only strictly needed for overlapping static
-regions, it must also be applied for dynamic regions to maintain a consistent
-order of all regions at all times. As each new region is mapped, existing
-entries in the translation tables are checked to ensure consistency. Please
-refer to the comments in the source code of the core module for more details
-about the sorting algorithm in use.
-
-.. [#granularity-ref] That is, when mmap regions do not enforce their mapping
- granularity.
-
-TLB maintenance operations
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The library takes care of performing TLB maintenance operations when required.
-For example, when the user requests removing a dynamic region, the library
-invalidates all TLB entries associated to that region to ensure that these
-changes are visible to subsequent execution, including speculative execution,
-that uses the changed translation table entries.
-
-A counter-example is the initialization of translation tables. In this case,
-explicit TLB maintenance is not required. The Armv8-A architecture guarantees
-that all TLBs are disabled from reset and their contents have no effect on
-address translation at reset [#tlb-reset-ref]_. Therefore, the TLBs invalidation
-is deferred to the ``enable_mmu*()`` family of functions, just before the MMU is
-turned on.
-
-TLB invalidation is not required when adding dynamic regions either. Dynamic
-regions are not allowed to overlap existing memory region. Therefore, if the
-dynamic mapping request is deemed legitimate, it automatically concerns memory
-that was not mapped in this translation regime and the library will have
-initialized its corresponding translation table entry to an invalid
-descriptor. Given that the TLBs are not architecturally permitted to hold any
-invalid translation table entry [#tlb-no-invalid-entry]_, this means that this
-mapping cannot be cached in the TLBs.
-
-.. [#tlb-reset-ref] See section D4.9 `Translation Lookaside Buffers (TLBs)`, subsection `TLB behavior at reset` in Armv8-A, rev C.a.
-.. [#tlb-no-invalid-entry] See section D4.10.1 `General TLB maintenance requirements` in Armv8-A, rev C.a.
-
---------------
-
-*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
-
-.. _lib/xlat_tables_v2: ../lib/xlat_tables_v2
-.. _lib/xlat_tables: ../lib/xlat_tables
-.. _xlat_tables_v2.h: ../include/lib/xlat_tables/xlat_tables_v2.h
-.. _xlat_tables_context.c: ../lib/xlat_tables_v2/xlat_tables_context.c
-.. _xlat_tables_core.c: ../lib/xlat_tables_v2/xlat_tables_core.c
-.. _xlat_tables_utils.c: ../lib/xlat_tables_v2/xlat_tables_utils.c
-.. _aarch32/xlat_tables_arch.c: ../lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
-.. _aarch64/xlat_tables_arch.c: ../lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
-.. _Porting Guide: porting-guide.rst
-.. |Alignment Example| image:: ./diagrams/xlat_align.png?raw=true
+++ /dev/null
-Trusted Firmware-A maintainers
-==============================
-
-Trusted Firmware-A (TF-A) is an Arm maintained project. All contributions are
-ultimately merged by the maintainers listed below. Technical ownership of some
-parts of the codebase is delegated to the sub-maintainers listed below. An
-acknowledgement from these sub-maintainers may be required before the
-maintainers merge a contribution.
-
-Main maintainers
-----------------
-:G: `danh-arm`_
-:G: `dp-arm`_
-:G: `soby-mathew`_
-
-Allwinner ARMv8 platform port
------------------------------
-:G: `Andre-ARM`_
-:G: `smaeul`_
-:F: docs/plat/allwinner.rst
-:F: plat/allwinner/
-:F: drivers/allwinner/
-
-Amlogic Meson S905 (GXBB) platform port
----------------------------------------
-:G: `Andre-ARM`_
-:F: docs/plat/meson-gxbb.rst
-:F: drivers/meson/
-:F: plat/meson/gxbb/
-
-Amlogic Meson S905x (GXL) platform port
----------------------------------------
-:G: `remi-triplefault`_
-:F: docs/plat/meson-gxl.rst
-:F: drivers/meson/gxl
-:F: plat/meson/gxl/
-
-Armv7-A architecture port
--------------------------
-:G: `etienne-lms`_
-
-Arm System Guidance for Infrastructure / Mobile FVP platforms
--------------------------------------------------------------
-:G: `npoushin`_
-:G: `thomas-arm`_
-:F: plat/arm/css/sgi/
-:F: plat/arm/css/sgm/
-:F: plat/arm/board/sgi575/
-:F: plat/arm/board/sgm775/
-
-Console API framework
----------------------
-:G: `jwerner-chromium`_
-:F: drivers/console/
-:F: include/drivers/console.h
-:F: plat/common/aarch64/crash_console_helpers.S
-
-coreboot support libraries
---------------------------
-:G: `jwerner-chromium`_
-:F: drivers/coreboot/
-:F: include/drivers/coreboot/
-:F: include/lib/coreboot.h
-:F: lib/coreboot/
-
-eMMC/UFS drivers
-----------------
-:G: `hzhuang1`_
-:F: drivers/partition/
-:F: drivers/synopsys/emmc/
-:F: drivers/synopsys/ufs/
-:F: drivers/ufs/
-:F: include/drivers/dw_ufs.h
-:F: include/drivers/ufs.h
-:F: include/drivers/synopsys/dw_mmc.h
-
-HiSilicon HiKey and HiKey960 platform ports
--------------------------------------------
-:G: `hzhuang1`_
-:F: docs/plat/hikey.rst
-:F: docs/plat/hikey960.rst
-:F: plat/hisilicon/hikey/
-:F: plat/hisilicon/hikey960/
-
-HiSilicon Poplar platform port
-------------------------------
-:G: `shawnguo2`_
-:F: docs/plat/poplar.rst
-:F: plat/hisilicon/poplar/
-
-Intel SocFPGA platform ports
-----------------------------
-:G: `thloh85-intel`
-:F: plat/intel/soc
-
-MediaTek platform ports
------------------------
-:G: `mtk09422`_
-:F: plat/mediatek/
-
-Marvell platform ports and SoC drivers
---------------------------------------
-:G: `kostapr`_
-:F: docs/marvell/
-:F: plat/marvell/
-:F: drivers/marvell/
-:F: tools/marvell/
-
-NVidia platform ports
----------------------
-:G: `vwadekar`_
-:F: docs/plat/nvidia-tegra.rst
-:F: include/lib/cpus/aarch64/denver.h
-:F: lib/cpus/aarch64/denver.S
-:F: plat/nvidia/
-
-NXP QorIQ Layerscape platform ports
------------------------------------
-:G: `qoriq-open-source`_
-:F: docs/plat/ls1043a.rst
-:F: plat/layerscape/
-
-NXP i.MX 7 WaRP7 platform port and SoC drivers
-----------------------------------------------
-:G: `bryanodonoghue`_
-:G: `niej`_
-:F: docs/plat/warp7.rst
-:F: plat/imx/common/
-:F: plat/imx/imx7/
-:F: drivers/imx/timer/
-:F: drivers/imx/uart/
-:F: drivers/imx/usdhc/
-
-NXP i.MX 8 platform port
-------------------------
-:G: `Anson-Huang`_
-:F: docs/plat/imx8.rst
-:F: plat/imx/
-
-NXP i.MX8M platform port
-------------------------
-:G: `JackyBai`_
-:F: doc/plat/imx8m.rst
-:F: plat/imx/imx8m/
-
-OP-TEE dispatcher
------------------
-:G: `jenswi-linaro`_
-:F: docs/spd/optee-dispatcher.rst
-:F: services/spd/opteed/
-
-QEMU platform port
-------------------
-:G: `jenswi-linaro`_
-:F: docs/plat/qemu.rst
-:F: plat/qemu/
-
-Raspberry Pi 3 platform port
-----------------------------
-:G: `grandpaul`_
-:F: docs/plat/rpi3.rst
-:F: plat/rpi3/
-:F: drivers/rpi3/
-:F: include/drivers/rpi3/
-
-Renesas rcar-gen3 platform port
--------------------------------
-:G: `ldts`_
-:G: `marex`_
-:F: docs/plat/rcar-gen3.rst
-:F: plat/renesas/rcar
-:F: drivers/renesas/rcar
-:F: tools/renesas/rcar_layout_create
-
-RockChip platform port
-----------------------
-:G: `TonyXie06`_
-:G: `rockchip-linux`_
-:G: `mmind`_
-:F: plat/rockchip/
-
-STM32MP1 platform port
-----------------------
-:G: `Yann-lms`_
-:F: docs/plat/stm32mp1.rst
-:F: drivers/st/
-:F: fdts/stm32\*
-:F: include/drivers/st/
-:F: include/dt-bindings/\*/stm32\*
-:F: plat/st/
-:F: tools/stm32image/
-
-Synquacer platform port
------------------------
-:G: `b49020`_
-:F: docs/plat/synquacer.rst
-:F: plat/socionext/synquacer/
-
-Texas Instruments platform port
--------------------------------
-:G: `glneo`_
-:F: docs/plat/ti-k3.rst
-:F: plat/ti/
-
-TLK/Trusty secure payloads
---------------------------
-:G: `vwadekar`_
-:F: docs/spd/tlk-dispatcher.rst
-:F: docs/spd/trusty-dispatcher.rst
-:F: include/bl32/payloads/tlk.h
-:F: services/spd/tlkd/
-:F: services/spd/trusty/
-
-UniPhier platform port
-----------------------
-:G: `masahir0y`_
-:F: docs/plat/socionext-uniphier.rst
-:F: plat/socionext/uniphier/
-
-Xilinx platform port
---------------------
-:G: `sivadur`_
-:F: docs/plat/xilinx-zynqmp.rst
-:F: plat/xilinx/
-
-.. _Andre-ARM: https://github.com/Andre-ARM
-.. _Anson-Huang: https://github.com/Anson-Huang
-.. _bryanodonoghue: https://github.com/bryanodonoghue
-.. _b49020: https://github.com/b49020
-.. _danh-arm: https://github.com/danh-arm
-.. _dp-arm: https://github.com/dp-arm
-.. _etienne-lms: https://github.com/etienne-lms
-.. _glneo: https://github.com/glneo
-.. _hzhuang1: https://github.com/hzhuang1
-.. _JackyBai: https://github.com/JackyBai
-.. _jenswi-linaro: https://github.com/jenswi-linaro
-.. _ldts: https://github.com/ldts
-.. _marex: https://github.com/marex
-.. _niej: https://github.com/niej
-.. _kostapr: https://github.com/kostapr
-.. _masahir0y: https://github.com/masahir0y
-.. _mmind: https://github.com/mmind
-.. _mtk09422: https://github.com/mtk09422
-.. _npoushin: https://github.com/npoushin
-.. _qoriq-open-source: https://github.com/qoriq-open-source
-.. _remi-triplefault: https://github.com/repk
-.. _rockchip-linux: https://github.com/rockchip-linux
-.. _shawnguo2: https://github.com/shawnguo2
-.. _sivadur: https://github.com/sivadur
-.. _smaeul: https://github.com/smaeul
-.. _soby-mathew: https://github.com/soby-mathew
-.. _thomas-arm: https://github.com/thomas-arm
-.. _TonyXie06: https://github.com/TonyXie06
-.. _vwadekar: https://github.com/vwadekar
-.. _Yann-lms: https://github.com/Yann-lms
-.. _grandpaul: https://github.com/grandpaul
-.. _jwerner-chromium: https://github.com/jwerner-chromium